4 个版本
0.1.3 | 2022 年 5 月 19 日 |
---|---|
0.1.2 | 2022 年 5 月 18 日 |
0.1.1 | 2022 年 5 月 18 日 |
0.1.0 | 2022 年 5 月 17 日 |
#14 in #banking
75KB
2K SLoC
Sila 银行 API for Rust
本软件包旨在减少 Rust 开发者将应用程序与 Sila 银行 API 集成的努力。
这是一个早期的工作进度。目前的工作重点在于建立与 API 交互的框架,并开始构建特定于 Sila 端点提供的功能的模块。
请注意,此软件包不是官方的 Sila 项目。我(Justin)与 Sila 有联系,但我建立这个是为了我自己的目的(我喜欢 Rust,并想用它来与我们的平台交互)。任何问题的解决应通过项目的 GitHub 仓库寻求。
示例
可以通过以下方式调用 Sila 的 check_handle
端点。
所有的 silamoney::
函数都是 async
,因此您需要使用适当的运行时,如 tokio
。
#[tokio::main]
async fn main() {
本节定义了在调用 Sila API 时的地址。
// you'll need your registered application's address and key; we define those here with these
// variable names to streamline the KeyParams constructor further down
let address = "0x...".to_string();
let private_key = Option::from("0x...".to_string());
这些 fn
引用在 silamoney::*
中构建了一个 JSON 对象,该对象将根据 Sila API 的预期发送到 Sila。
let message = serde_json::to_string(&HeaderMessage::from(CheckHandleMessageParams {
sila_handle: "handle-to-check".to_string(),
})).unwrap();
此函数准备要由您使用的任何 Signer
签名的数据。我们将使用 default_sign
。
由于 check_handle
不需要 usersignature
,因此向函数提供了 Option::None
以跳过该签名的创建。对于 KeyParams
,我们只需要指定先前定义的变量名称,因为它们与 struct
的预期相匹配。
let sdp = SignDataPair::from(SignDataParams {
message: message.clone(),
user_params: Option::None,
app_params: KeyParams { address, private_key },
});
silamoney
软件包中存在指定自定义签名的功能。此 default_sign
函数构建一个需要应用程序直接访问客户私钥的 Signer。
let signatures = default_sign(sdp.user, sdp.app).await;
该结构体位于 silamoney::SignedMessageParams
。它用于向 check_handle
端点发送请求。
let smp = SignedMessageParams {
ethereum_address: address.clone(),
sila_handle: handle.to_string(),
message: message.clone(),
usersignature: Option::None,
authsignature: signatures.authsignature,
};
check_handle
函数位于 silamoney::*
中,执行对 Sila API 的请求并等待响应。
let response = check_handle(&smp).await;
println!("Response: {:?}", serde_json::to_string(&response.unwrap()));
}
身份验证
Sila API 使用一种身份验证机制,该机制利用了以太坊项目确立的关键生成和消息签名标准。这个库包含多个结构和函数,以允许您使用用户私钥来签名消息,并以此方式使用 API。
您也可以选择定义自己的 Signer
,并为它提供一个闭包以生成执行该身份验证所需的签名。例如,您可能有一个独立的服务,它提供了一个 /sign
端点,您可以在那里提供用户地址和待签名消息,并由该服务处理生成该签名所需的敏感操作。以下是如何实现这一点的示例
#[derive(Deserialize, Serialize)]
struct CustomResponse {
signature: String
}
#[derive(Deserialize, Serialize)]
struct SilaSignServiceParams {
address: String,
message: String
}
let app_address = H160::from_str("0x...").unwrap();
let mut app_data = SignData {
address: *app_address.as_fixed_bytes(),
data: hash,
private_key: Option::None,
};
let signer = Signer::new(async move |&mut x| {
let url = format!("{}/sila/sign", env::var("SIGN_SVC_URL").expect("SIGN_SVC_URL must be set"));
let address = &format!("{:#x}", H160::from_slice(&x.address));
let message = hex::encode(&x.data);
let params = SilaSignServiceParams { address, message };
let client = reqwest::Client::new();
let resp = client
.post(&url)
.json(¶ms)
.send()
.await
.unwrap()
.json::<CustomResponse>()
.await
.unwrap();
Signature { data: resp.text.unwrap() }
});
let signature = signer.sign(&mut app_data).await;
通过这种方式,您可以在您的服务周围建立一些合理的架构安全边界。
依赖项
~15–32MB
~422K SLoC