Skip to content

Commit

Permalink
Add /inscription/:query/:child_number route
Browse files Browse the repository at this point in the history
  • Loading branch information
casey committed May 23, 2024
1 parent 4a33921 commit e3aaac1
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 3 deletions.
18 changes: 18 additions & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,7 @@ impl Index {
pub(crate) fn inscription_info(
&self,
query: query::Inscription,
child: Option<usize>,
) -> Result<Option<(api::Inscription, Option<TxOut>, Inscription)>> {
let rtx = self.database.begin_read()?;

Expand All @@ -1908,6 +1909,23 @@ impl Index {
return Ok(None);
};

let sequence_number = if let Some(child) = child {
let Some(child) = rtx
.open_multimap_table(SEQUENCE_NUMBER_TO_CHILDREN)?
.get(sequence_number)?
.skip(child)
.next()
.transpose()?
.map(|child| child.value())
else {
return Ok(None);
};

child
} else {
sequence_number
};

let sequence_number_to_inscription_entry =
rtx.open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY)?;

Expand Down
88 changes: 85 additions & 3 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ impl Server {
.route("/feed.xml", get(Self::feed))
.route("/input/:block/:transaction/:input", get(Self::input))
.route("/inscription/:inscription_query", get(Self::inscription))
.route(
"/inscription/:inscription_query/:child",
get(Self::inscription_child),
)
.route("/inscriptions", get(Self::inscriptions))
.route("/inscriptions", post(Self::inscriptions_json))
.route("/inscriptions/:page", get(Self::inscriptions_paginated))
Expand Down Expand Up @@ -1588,8 +1592,27 @@ impl Server {
async fn inscription(
Extension(server_config): Extension<Arc<ServerConfig>>,
Extension(index): Extension<Arc<Index>>,
AcceptJson(accept_json): AcceptJson,
Path(DeserializeFromStr(query)): Path<DeserializeFromStr<query::Inscription>>,
) -> ServerResult {
Self::inscription_inner(server_config, &index, accept_json, query, None).await
}

async fn inscription_child(
Extension(server_config): Extension<Arc<ServerConfig>>,
Extension(index): Extension<Arc<Index>>,
AcceptJson(accept_json): AcceptJson,
Path((DeserializeFromStr(query), child)): Path<(DeserializeFromStr<query::Inscription>, usize)>,
) -> ServerResult {
Self::inscription_inner(server_config, &index, accept_json, query, Some(child)).await
}

async fn inscription_inner(
server_config: Arc<ServerConfig>,
index: &Index,
accept_json: bool,
query: query::Inscription,
child: Option<usize>,
) -> ServerResult {
task::block_in_place(|| {
if let query::Inscription::Sat(_) = query {
Expand All @@ -1599,7 +1622,7 @@ impl Server {
}

let (info, txout, inscription) = index
.inscription_info(query)?
.inscription_info(query, child)?
.ok_or_not_found(|| format!("inscription {query}"))?;

Ok(if accept_json {
Expand Down Expand Up @@ -1643,7 +1666,7 @@ impl Server {
for inscription in inscriptions {
let query = query::Inscription::Id(inscription);
let (info, _, _) = index
.inscription_info(query)?
.inscription_info(query, None)?
.ok_or_not_found(|| format!("inscription {query}"))?;

response.push(info);
Expand Down Expand Up @@ -2305,7 +2328,12 @@ mod tests {
regex: impl AsRef<str>,
) {
let response = self.get(path);
assert_eq!(response.status(), status);
assert_eq!(
response.status(),
status,
"response: {}",
response.text().unwrap()
);
assert_regex_match!(response.text().unwrap(), regex.as_ref());
}

Expand Down Expand Up @@ -5251,6 +5279,60 @@ next
);
}

#[test]
fn inscription_child() {
let server = TestServer::builder().chain(Chain::Regtest).build();
server.mine_blocks(1);

let parent_txid = server.core.broadcast_tx(TransactionTemplate {
inputs: &[(1, 0, 0, inscription("text/plain", "hello").to_witness())],
..default()
});

server.mine_blocks(1);

let parent_inscription_id = InscriptionId {
txid: parent_txid,
index: 0,
};

let child_txid = server.core.broadcast_tx(TransactionTemplate {
inputs: &[
(
2,
0,
0,
Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
parents: vec![parent_inscription_id.value()],
..default()
}
.to_witness(),
),
(2, 1, 0, Default::default()),
],
..default()
});

server.mine_blocks(1);

let child_inscription_id = InscriptionId {
txid: child_txid,
index: 0,
};

server.assert_response_regex(
format!("/inscription/{parent_inscription_id}/0"),
StatusCode::OK,
format!(
".*<title>Inscription 1</title>.*
.*<dt>id</dt>
.*<dd class=monospace>{child_inscription_id}</dd>.*"
),
);
}

#[test]
fn inscription_with_parent_page() {
let server = TestServer::builder().chain(Chain::Regtest).build();
Expand Down

0 comments on commit e3aaac1

Please sign in to comment.