Skip to content

Commit

Permalink
Compute authorization header from url
Browse files Browse the repository at this point in the history
  • Loading branch information
ninegua committed Oct 26, 2024
1 parent 38a3620 commit 5741961
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rs/bitcoin/kyt/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ rust_library(
# Keep sorted.
"//rs/rust_canisters/http_types",
"@crate_index//:askama",
"@crate_index//:base64",
"@crate_index//:bitcoin_0_32",
"@crate_index//:candid",
"@crate_index//:ciborium",
Expand All @@ -29,6 +30,7 @@ rust_library(
"@crate_index//:serde",
"@crate_index//:serde_json",
"@crate_index//:time",
"@crate_index//:url",
],
)

Expand Down
2 changes: 2 additions & 0 deletions rs/bitcoin/kyt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ path = "src/main.rs"

[dependencies]
askama = { workspace = true }
base64 = { workspace = true }
bitcoin = { version = "0.32.2", default-features = false }
candid = { workspace = true }
ciborium = { workspace = true }
Expand All @@ -24,6 +25,7 @@ ic-stable-structures = { workspace = true }
serde = { workspace = true }
serde_json = {workspace = true }
time = { workspace = true }
url = { workspace = true }

[dev-dependencies]
candid_parser = { workspace = true }
Expand Down
9 changes: 7 additions & 2 deletions rs/bitcoin/kyt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,15 @@ impl FetchEnv for KytCanisterEnv {
txid: Txid,
max_response_bytes: u32,
) -> Result<Transaction, HttpGetTxError> {
let request = provider.create_request(txid, max_response_bytes);
let request = provider
.create_request(txid, max_response_bytes)
.map_err(|err| HttpGetTxError::Rejected {
code: RejectionCode::SysFatal,
message: err,
})?;
let url = request.url.clone();
let cycles = get_tx_cycle_cost(max_response_bytes);
match http_request(request, cycles).await {
match http_request(request.clone(), cycles).await {
Ok((response,)) => {
// Ensure response is 200 before decoding
if response.status != 200u32 {
Expand Down
45 changes: 34 additions & 11 deletions rs/bitcoin/kyt/src/providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,26 @@ impl Provider {
&self,
txid: Txid,
max_response_bytes: u32,
) -> CanisterHttpRequestArgument {
) -> Result<CanisterHttpRequestArgument, String> {
match (self.provider_id, &self.btc_network) {
(_, BtcNetwork::Regtest { json_rpc_url }) => {
make_post_request(json_rpc_url, txid, max_response_bytes)
}
(ProviderId::Blockstream, _) => make_get_request(
(ProviderId::Blockstream, _) => Ok(make_get_request(
"blockstream.info",
&self.btc_network,
txid,
max_response_bytes,
),
(ProviderId::MempoolSpace, _) => {
make_get_request("mempool.space", &self.btc_network, txid, max_response_bytes)
)),
(ProviderId::MempoolSpace, _) => Ok(make_get_request(
"mempool.space",
&self.btc_network,
txid,
max_response_bytes,
)),
(ProviderId::Btcscan, BtcNetwork::Mainnet) => {
Ok(btcscan_request(txid, max_response_bytes))
}
(ProviderId::Btcscan, BtcNetwork::Mainnet) => btcscan_request(txid, max_response_bytes),
(provider, btc_network) => {
panic!(
"Provider {} does not support bitcoin {}",
Expand Down Expand Up @@ -152,23 +157,41 @@ fn make_post_request(
json_rpc_url: &str,
txid: Txid,
max_response_bytes: u32,
) -> CanisterHttpRequestArgument {
) -> Result<CanisterHttpRequestArgument, String> {
let mut url = url::Url::parse(json_rpc_url).map_err(|err| err.to_string())?;
let username = url.username();
let password = url.password().unwrap_or_default();
let authorization = base64::encode(format!(
"{}:{}",
url::form_urlencoded::parse(username.as_bytes())
.next()
.ok_or(format!("Failed to url_decode {}", username))?
.0,
url::form_urlencoded::parse(password.as_bytes())
.next()
.ok_or(format!("Failed to url_decode {}", password))?
.0,
));
url.set_username("")
.map_err(|()| format!("Invalid JSON RPC URL {}", json_rpc_url))?;
url.set_password(None)
.map_err(|()| format!("Invalid JSON RPC URL {}", json_rpc_url))?;
let request_headers = vec![HttpHeader {
name: "Authorization".to_string(),
value: "Basic aWMtYnRjLWludGVncmF0aW9uOlFQUWlOYXBoMTlGcVVzQ3JCUk4wRklJN2x5TTI2QjUxZkFNZUJRekNiLUU9".to_string(),
value: format!("Basic {}", authorization),
}];
let body = format!(
"{{\"method\": \"gettransaction\", \"params\": [\"{}\"]}}",
txid
);
CanisterHttpRequestArgument {
url: json_rpc_url.to_string(),
Ok(CanisterHttpRequestArgument {
url: url.to_string(),
method: HttpMethod::POST,
body: Some(body.as_bytes().to_vec()),
max_response_bytes: Some(max_response_bytes as u64),
transform: param_transform(),
headers: request_headers,
}
})
}

fn param_transform() -> Option<TransformContext> {
Expand Down
2 changes: 1 addition & 1 deletion rs/tests/ckbtc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ DEPENDENCIES = [
# Keep sorted.
"//packages/icrc-ledger-agent:icrc_ledger_agent",
"//packages/icrc-ledger-types:icrc_ledger_types",
"//rs/bitcoin/kyt:btc_kyt_lib",
"//rs/bitcoin/ckbtc/agent",
"//rs/bitcoin/ckbtc/kyt",
"//rs/bitcoin/ckbtc/minter",
"//rs/bitcoin/kyt:btc_kyt_lib",
"//rs/canister_client",
"//rs/config",
"//rs/ledger_suite/icp:icp_ledger",
Expand Down

0 comments on commit 5741961

Please sign in to comment.