diff --git a/docs/src/inscriptions/recursion.md b/docs/src/inscriptions/recursion.md index 3944413c54..37f8e80e2e 100644 --- a/docs/src/inscriptions/recursion.md +++ b/docs/src/inscriptions/recursion.md @@ -33,10 +33,10 @@ Recursion has a number of interesting use-cases: ## Endpoints
- + GET /content/<INSCRIPTION_ID> - + ### Description The content of the inscription with `` @@ -50,67 +50,67 @@ curl -s -H "Accept: application/json" \
- + GET /r/blockhash - + ### Description -Latest block hash in text. +Latest block hash. ### Example ```bash curl -s \ http://0.0.0.0:80/r/blockhash ``` -```text +```json "00000000000000000002891b440944e0ce40b37b6ccaa138c280e9edfc319d5d" ```
- + GET /r/blockhash/<HEIGHT> - + ### Description -Block hash at given block height in text. +Block hash at given block height as JSON string. ### Example ```bash curl -s \ http://0.0.0.0:80/r/blockhash/840000 ``` -```text +```json "0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5" ```
- + GET /r/blockheight - + ### Description -Latest block height in text. +Latest block height. ### Example ```bash curl -s \ http://0.0.0.0:80/r/blockheight ``` -```text +```json 866393 ```
- + GET /r/blockinfo/<QUERY> - + ### Description Block info. `` may be a block height or block hash. @@ -207,29 +207,29 @@ curl -s -H "Accept: application/json" \
- + GET /r/blocktime - + ### Description -UNIX time stamp of latest block in text. +UNIX time stamp of latest block. ### Example ```bash curl -s \ http://0.0.0.0:80/r/blocktime ``` -```text +```json 1729362253 ```
- + GET /r/children/<INSCRIPTION_ID> - + ### Description The first 100 child inscription ids. @@ -350,10 +350,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/children/<INSCRIPTION_ID>/<PAGE> - + ### Description The set of 100 child inscription ids on ``. @@ -474,10 +474,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/children/<INSCRIPTION_ID>/inscriptions - + ### Description Details of the first 100 child inscriptions. @@ -1796,10 +1796,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/children/<INSCRIPTION_ID>/inscriptions/<PAGE> - + ### Description Details of the set of 100 child inscriptions on <PAGE>. @@ -3119,10 +3119,22 @@ curl -s -H "Accept: application/json" \
- + + GET + /r/undelegated-content/<INSCRIPTION_ID> + + +### Description +Undelegated content of an inscription. + +
+ + +
+ GET /r/inscription/<INSCRIPTION_ID> - + ### Description Information about an inscription. @@ -3155,10 +3167,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/metadata/<INSCRIPTION_ID> - + ### Description JSON string containing the hex-encoded CBOR metadata. @@ -3174,10 +3186,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/parents/<INSCRIPTION_ID> - + ### Description The first 100 parent inscription ids. @@ -3199,10 +3211,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/parents/<INSCRIPTION_ID>/<PAGE> - + ### Description The set of 100 parent inscription ids on ``. @@ -3222,10 +3234,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/sat/<SAT_NUMBER> - + ### Description The first 100 inscription ids on a sat. Requires index with `--index-sats` flag. @@ -3250,10 +3262,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/sat/<SAT_NUMBER>/<PAGE> - + ### Description The set of 100 inscription ids on ``. Requires index with `--index-sats` flag. @@ -3285,10 +3297,10 @@ curl -s -H "Accept: application/json" \
- + GET /r/sat/<SAT_NUMBER>/at/<INDEX> - + ### Description The inscription id at `` of all inscriptions on a sat. `` may be a negative number to index from the back. `0` being the first and `-1` being the most recent for example. Requires index with `--index-sats` flag. diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 8cc7763f57..d711bd7761 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -236,6 +236,10 @@ impl Server { "/r/children/:inscription_id/inscriptions/:page", get(Self::child_inscriptions_recursive_paginated), ) + .route( + "/r/undelegated-content/:inscription_id", + get(Self::undelegated_content), + ) .route("/r/metadata/:inscription_id", get(Self::metadata)) .route("/r/parents/:inscription_id", get(Self::parents_recursive)) .route( @@ -1467,6 +1471,30 @@ impl Server { }) } + async fn undelegated_content( + Extension(index): Extension>, + Extension(settings): Extension>, + Extension(server_config): Extension>, + Path(inscription_id): Path, + accept_encoding: AcceptEncoding, + ) -> ServerResult { + task::block_in_place(|| { + if settings.is_hidden(inscription_id) { + return Ok(PreviewUnknownHtml.into_response()); + } + + let inscription = index + .get_inscription_by_id(inscription_id)? + .ok_or_not_found(|| format!("inscription {inscription_id}"))?; + + Ok( + Self::content_response(inscription, accept_encoding, &server_config)? + .ok_or_not_found(|| format!("inscription {inscription_id} content"))? + .into_response(), + ) + }) + } + fn content_response( inscription: Inscription, accept_encoding: AcceptEncoding, @@ -6576,6 +6604,81 @@ next ); } + #[test] + fn undelegated_content() { + let server = TestServer::builder().chain(Chain::Regtest).build(); + + server.mine_blocks(1); + + let delegate = Inscription { + content_type: Some("text/plain".into()), + body: Some("foo".into()), + ..default() + }; + + let delegate_txid = server.core.broadcast_tx(TransactionTemplate { + inputs: &[(1, 0, 0, delegate.to_witness())], + ..default() + }); + + let delegate_id = InscriptionId { + txid: delegate_txid, + index: 0, + }; + + server.mine_blocks(1); + + let inscription = Inscription { + content_type: Some("text/plain".into()), + body: Some("bar".into()), + delegate: Some(delegate_id.value()), + ..default() + }; + + let txid = server.core.broadcast_tx(TransactionTemplate { + inputs: &[(2, 0, 0, inscription.to_witness())], + ..default() + }); + + server.mine_blocks(1); + + let id = InscriptionId { txid, index: 0 }; + + server.assert_response( + format!("/r/undelegated-content/{id}"), + StatusCode::OK, + "bar", + ); + + server.assert_response(format!("/content/{id}"), StatusCode::OK, "foo"); + + // Test normal inscription without delegate + let normal_inscription = Inscription { + content_type: Some("text/plain".into()), + body: Some("baz".into()), + ..default() + }; + + let normal_txid = server.core.broadcast_tx(TransactionTemplate { + inputs: &[(3, 0, 0, normal_inscription.to_witness())], + ..default() + }); + + server.mine_blocks(1); + + let normal_id = InscriptionId { + txid: normal_txid, + index: 0, + }; + + server.assert_response( + format!("/r/undelegated-content/{normal_id}"), + StatusCode::OK, + "baz", + ); + server.assert_response(format!("/content/{normal_id}"), StatusCode::OK, "baz"); + } + #[test] fn content_proxy() { let server = TestServer::builder().chain(Chain::Regtest).build();