您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

integration.rs 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. use common_api::crypto::prelude::*;
  2. use near_client::client::{Finality, NearClient, Signer};
  3. use near_primitives::{account::id::AccountId, types::Balance};
  4. use rand::{RngCore, SeedableRng};
  5. use rand_chacha::ChaChaRng;
  6. use serde::{Deserialize, Serialize};
  7. use std::str::FromStr;
  8. use url::Url;
  9. use wasm_bindgen::JsValue;
  10. use wasm_bindgen_futures::JsFuture;
  11. use wasm_bindgen_test::*;
  12. use web_client::{KeyProvisioner, ProvisionerConfig};
  13. wasm_bindgen_test_configure!(run_in_browser);
  14. #[derive(Serialize, Deserialize)]
  15. struct ValidatorKey {
  16. account_id: AccountId,
  17. public_key: Ed25519PublicKey,
  18. secret_key: String,
  19. }
  20. fn random_bits() -> [u8; 32] {
  21. let mut chacha = ChaChaRng::from_entropy();
  22. let mut secret_bytes = [0_u8; 32];
  23. chacha.fill_bytes(&mut secret_bytes);
  24. secret_bytes
  25. }
  26. async fn create_account(
  27. client: &NearClient,
  28. validator: &Signer,
  29. account_id_str: &str,
  30. amount: Balance,
  31. ) -> anyhow::Result<Signer> {
  32. let id = AccountId::from_str(account_id_str)?;
  33. let sk = Ed25519SecretKey::try_from_bytes(&random_bits())?;
  34. let pk = Ed25519PublicKey::from(&sk);
  35. client
  36. .create_account(validator, &id, pk, amount)
  37. .commit(Finality::Final)
  38. .await?;
  39. let nonce = Result::from(
  40. client
  41. .view_access_key(&id, &pk, Finality::Optimistic)
  42. .await
  43. .unwrap(),
  44. )
  45. .map_err(|err| anyhow::anyhow!(err))?;
  46. Ok(Signer::from_secret(sk, id, nonce))
  47. }
  48. async fn delete_account(
  49. client: &NearClient,
  50. signer: &Signer,
  51. beneficiary_acc_id: &AccountId,
  52. ) -> anyhow::Result<()> {
  53. let id = signer.account().clone();
  54. let pk = signer.public_key();
  55. let nonce = Result::from(client.view_access_key(&id, pk, Finality::Final).await?)
  56. .map_err(|err| anyhow::anyhow!(err))?;
  57. signer.update_nonce(nonce);
  58. client
  59. .delete_account(signer, &id, beneficiary_acc_id)
  60. .commit(Finality::Final)
  61. .await?;
  62. Ok(())
  63. }
  64. async fn validator_key() -> anyhow::Result<ValidatorKey> {
  65. Ok(
  66. reqwest::get("http://sandbox-artifact:3032/validator_key.json")
  67. .await?
  68. .json::<ValidatorKey>()
  69. .await?,
  70. )
  71. }
  72. async fn validator_account(
  73. client: &NearClient,
  74. validator_key: ValidatorKey,
  75. ) -> anyhow::Result<Signer> {
  76. let key_nonce = Result::from(
  77. client
  78. .view_access_key(
  79. &validator_key.account_id,
  80. &validator_key.public_key,
  81. Finality::Final,
  82. )
  83. .await?,
  84. )
  85. .map_err(|err| anyhow::anyhow!(err))?;
  86. let signer = Signer::from_secret_str(
  87. &validator_key.secret_key,
  88. validator_key.account_id.clone(),
  89. key_nonce,
  90. )?;
  91. Ok(signer)
  92. }
  93. async fn meeting_room_contract() -> anyhow::Result<Vec<u8>> {
  94. Ok(
  95. reqwest::get("http://contract-artifact:3033/meeting_room.wasm")
  96. .await?
  97. .bytes()
  98. .await?
  99. .to_vec(),
  100. )
  101. }
  102. #[wasm_bindgen_test]
  103. async fn pass() {
  104. console_log!("Test Passed");
  105. }
  106. #[wasm_bindgen_test]
  107. async fn key_exchange() {
  108. let rpc_url = Url::parse("http://sandbox:3030").unwrap();
  109. let client = NearClient::new(rpc_url).unwrap();
  110. let validator_key = validator_key().await.unwrap();
  111. let validator = validator_account(&client, validator_key).await.unwrap();
  112. // create account for key-exchange
  113. // Alice is an initiator account
  114. let alice_sg = create_account(
  115. &client,
  116. &validator,
  117. "alice.test.near",
  118. near_units::near::parse("10 N").unwrap(),
  119. )
  120. .await
  121. .unwrap();
  122. let bob_sg = create_account(
  123. &client,
  124. &validator,
  125. "bob.test.near",
  126. near_units::near::parse("10 N").unwrap(),
  127. )
  128. .await
  129. .unwrap();
  130. let karl_sg = create_account(
  131. &client,
  132. &validator,
  133. "karl.test.near",
  134. near_units::near::parse("10 N").unwrap(),
  135. )
  136. .await
  137. .unwrap();
  138. let mike_sg = create_account(
  139. &client,
  140. &validator,
  141. "mike.test.near",
  142. near_units::near::parse("10 N").unwrap(),
  143. )
  144. .await
  145. .unwrap();
  146. // Create an contract account
  147. let contract_sg = create_account(
  148. &client,
  149. &validator,
  150. "contract.test.near",
  151. near_units::near::parse("200 N").unwrap(),
  152. )
  153. .await
  154. .unwrap();
  155. // Contract byte code
  156. let contract_wasm = meeting_room_contract().await.unwrap();
  157. let contract_id = contract_sg.account().clone();
  158. client
  159. .deploy_contract(&contract_sg, &contract_id, contract_wasm)
  160. .commit(Finality::Final)
  161. .await
  162. .unwrap();
  163. // config with endpoints
  164. let config = ProvisionerConfig::new(
  165. contract_id.to_string(),
  166. "http://sandbox:3030",
  167. "http://key-exchange:3000",
  168. )
  169. .unwrap();
  170. // Create provisioners for each user
  171. let keypair_str = alice_sg.secret_key().string();
  172. let provisioner = KeyProvisioner::new(
  173. keypair_str,
  174. alice_sg.nonce(),
  175. alice_sg.account().to_string(),
  176. config.clone(),
  177. )
  178. .unwrap();
  179. let arr = JsValue::from(
  180. &[
  181. bob_sg.account().to_string(),
  182. karl_sg.account().to_string(),
  183. mike_sg.account().to_string(),
  184. ]
  185. .into_iter()
  186. .map(|it| JsValue::from_str(&it))
  187. .collect::<js_sys::Array>(),
  188. );
  189. let set = js_sys::Set::new(&arr);
  190. // Init meeting
  191. let meeting_id = JsFuture::from(provisioner.init(set))
  192. .await
  193. .unwrap()
  194. .as_string()
  195. .unwrap();
  196. // Then each user push own key to blockchain
  197. let keypair_str = bob_sg.secret_key().string();
  198. let provisioner_bob = KeyProvisioner::new(
  199. keypair_str,
  200. bob_sg.nonce(),
  201. bob_sg.account().to_string(),
  202. config.clone(),
  203. )
  204. .unwrap();
  205. let _ = JsFuture::from(provisioner_bob.push_to_near(meeting_id.clone()))
  206. .await
  207. .unwrap();
  208. let keypair_str = karl_sg.secret_key().string();
  209. let provisioner_karl = KeyProvisioner::new(
  210. keypair_str,
  211. karl_sg.nonce(),
  212. karl_sg.account().to_string(),
  213. config.clone(),
  214. )
  215. .unwrap();
  216. let _ = JsFuture::from(provisioner_karl.push_to_near(meeting_id.clone()))
  217. .await
  218. .unwrap();
  219. let keypair_str = mike_sg.secret_key().string();
  220. let provisioner_mike = KeyProvisioner::new(
  221. keypair_str,
  222. mike_sg.nonce(),
  223. mike_sg.account().to_string(),
  224. config.clone(),
  225. )
  226. .unwrap();
  227. let _ = JsFuture::from(provisioner_mike.push_to_near(meeting_id.clone()))
  228. .await
  229. .unwrap();
  230. // Send encrypted keys to participants
  231. let alice_key = JsFuture::from(provisioner.send_keys(meeting_id.clone()))
  232. .await
  233. .unwrap()
  234. .as_string()
  235. .unwrap();
  236. // Fetch encrypted keys
  237. let bob_key = JsFuture::from(provisioner_bob.get_key(meeting_id.clone()))
  238. .await
  239. .unwrap()
  240. .as_string()
  241. .unwrap();
  242. let karl_key = JsFuture::from(provisioner_karl.get_key(meeting_id.clone()))
  243. .await
  244. .unwrap()
  245. .as_string()
  246. .unwrap();
  247. let mike_key = JsFuture::from(provisioner_mike.get_key(meeting_id.clone()))
  248. .await
  249. .unwrap()
  250. .as_string()
  251. .unwrap();
  252. assert!(&[mike_key, bob_key, karl_key]
  253. .into_iter()
  254. .all(|key| key == alice_key));
  255. // delete all accounts
  256. delete_account(&client, &contract_sg, validator.account())
  257. .await
  258. .unwrap();
  259. delete_account(&client, &alice_sg, validator.account())
  260. .await
  261. .unwrap();
  262. delete_account(&client, &bob_sg, validator.account())
  263. .await
  264. .unwrap();
  265. delete_account(&client, &karl_sg, validator.account())
  266. .await
  267. .unwrap();
  268. delete_account(&client, &mike_sg, validator.account())
  269. .await
  270. .unwrap();
  271. }
  272. #[wasm_bindgen_test]
  273. async fn sandbox() {}