-
Notifications
You must be signed in to change notification settings - Fork 82
/
Copy pathshared.rs
92 lines (80 loc) · 2.7 KB
/
shared.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::path::PathBuf;
use crate::xdr;
use clap::arg;
use crate::{
commands::contract::info::shared::Error::InvalidWasmHash,
config::{locator, network},
utils::rpc::get_remote_wasm_from_hash,
wasm::{self, Error::ContractIsStellarAsset},
};
#[derive(Debug, clap::Args, Clone, Default)]
#[command(group(
clap::ArgGroup::new("Source")
.required(true)
.args(& ["wasm", "wasm_hash", "contract_id"]),
))]
#[group(skip)]
pub struct Args {
/// Wasm file to extract the data from
#[arg(long, group = "Source")]
pub wasm: Option<PathBuf>,
/// Wasm hash to get the data for
#[arg(long = "wasm-hash", group = "Source")]
pub wasm_hash: Option<String>,
/// Contract id to get the data for
#[arg(long = "id", env = "STELLAR_CONTRACT_ID", group = "Source")]
pub contract_id: Option<String>,
#[command(flatten)]
pub network: network::Args,
#[command(flatten)]
pub locator: locator::Args,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum, Default)]
pub enum MetasInfoOutput {
/// Text output of the meta info entry
#[default]
Text,
/// XDR output of the info entry
XdrBase64,
/// JSON output of the info entry (one line, not formatted)
Json,
/// Formatted (multiline) JSON output of the info entry
JsonFormatted,
}
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Network(#[from] network::Error),
#[error(transparent)]
Wasm(#[from] wasm::Error),
#[error("provided wasm hash is invalid {0:?}")]
InvalidWasmHash(String),
#[error(transparent)]
Rpc(#[from] soroban_rpc::Error),
}
pub async fn fetch_wasm(args: &Args) -> Result<Option<Vec<u8>>, Error> {
let network = &args.network.get(&args.locator)?;
let wasm = if let Some(path) = &args.wasm {
wasm::Args { wasm: path.clone() }.read()?
} else if let Some(wasm_hash) = &args.wasm_hash {
let hash = hex::decode(wasm_hash)
.map_err(|_| InvalidWasmHash(wasm_hash.clone()))?
.try_into()
.map_err(|_| InvalidWasmHash(wasm_hash.clone()))?;
let hash = xdr::Hash(hash);
let client = network.rpc_client()?;
client
.verify_network_passphrase(Some(&network.network_passphrase))
.await?;
get_remote_wasm_from_hash(&client, &hash).await?
} else if let Some(contract_id) = &args.contract_id {
let res = wasm::fetch_from_contract(contract_id, network, &args.locator).await;
if let Some(ContractIsStellarAsset) = res.as_ref().err() {
return Ok(None);
}
res?
} else {
unreachable!("One of contract location arguments must be passed");
};
Ok(Some(wasm))
}