Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

integration.rs 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. use near_client::{crypto::prelude::*, prelude::*, Finality};
  2. use near_primitives_core::account::id::AccountId;
  3. use serde::{Deserialize, Serialize};
  4. use std::str::FromStr;
  5. use url::Url;
  6. use wasm_bindgen::JsValue;
  7. use wasm_bindgen_futures::JsFuture;
  8. use wasm_bindgen_test::*;
  9. use web_client::{KeyProvisioner, Meeting, ProvisionerConfig};
  10. wasm_bindgen_test_configure!(run_in_browser);
  11. const ALICE_BYTES: [u8; 32] = [1; 32];
  12. const BOB_BYTES: [u8; 32] = [2; 32];
  13. const KARL_BYTES: [u8; 32] = [3; 32];
  14. const MIKE_BYTES: [u8; 32] = [4; 32];
  15. const CONTRACT_BYTES: [u8; 32] = [5; 32];
  16. #[derive(Serialize, Deserialize)]
  17. struct ValidatorKey {
  18. account_id: AccountId,
  19. public_key: Ed25519PublicKey,
  20. secret_key: String,
  21. }
  22. async fn create_account(
  23. client: &NearClient,
  24. validator: &Signer,
  25. sk_bytes: &[u8; 32],
  26. id_str: &str,
  27. ) -> Signer {
  28. let id = AccountId::from_str(id_str).unwrap();
  29. let sk = Ed25519SecretKey::try_from_bytes(sk_bytes).unwrap();
  30. let pk = Ed25519PublicKey::from(&sk);
  31. let amount = near_units::near::parse("200 N").unwrap();
  32. client
  33. .create_account(validator, &id, pk, amount)
  34. .commit(Finality::Final)
  35. .await
  36. .unwrap();
  37. let nonce = Result::from(
  38. client
  39. .view_access_key(&id, &pk, Finality::None)
  40. .await
  41. .unwrap(),
  42. )
  43. .unwrap();
  44. Signer::from_secret(sk, id, nonce)
  45. }
  46. async fn drop_created_account(
  47. client: &NearClient,
  48. beneficiary_acc_id: &AccountId,
  49. sk_bytes: &[u8; 32],
  50. id_str: &str,
  51. ) {
  52. let id = AccountId::from_str(id_str).unwrap();
  53. let sk = Ed25519SecretKey::try_from_bytes(sk_bytes).unwrap();
  54. let pk = Ed25519PublicKey::from(&sk);
  55. if let Ok(access_key) = client.view_access_key(&id, &pk, Finality::Final).await {
  56. if let Ok(nonce) = access_key.into() {
  57. let signer = Signer::from_secret(sk, id.clone(), nonce);
  58. signer.update_nonce(nonce);
  59. client
  60. .delete_account(&signer, &id, beneficiary_acc_id)
  61. .commit(Finality::Final)
  62. .await
  63. .unwrap();
  64. };
  65. }
  66. }
  67. async fn validator_key() -> ValidatorKey {
  68. reqwest::get("http://sandbox-artifact:3032/validator_key.json")
  69. .await
  70. .unwrap()
  71. .json::<ValidatorKey>()
  72. .await
  73. .unwrap()
  74. }
  75. async fn validator_account(client: &NearClient, validator_key: ValidatorKey) -> 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. .unwrap(),
  85. )
  86. .unwrap();
  87. Signer::from_secret_str(
  88. &validator_key.secret_key,
  89. validator_key.account_id.clone(),
  90. key_nonce,
  91. )
  92. .unwrap()
  93. }
  94. async fn meeting_room_contract() -> Vec<u8> {
  95. reqwest::get("http://contract-artifact:3033/meet.wasm")
  96. .await
  97. .unwrap()
  98. .bytes()
  99. .await
  100. .unwrap()
  101. .to_vec()
  102. }
  103. #[wasm_bindgen_test]
  104. async fn key_exchange() {
  105. let rpc_url = Url::parse("http://sandbox:3030").unwrap();
  106. let client = NearClient::new(rpc_url).unwrap();
  107. let validator_key = validator_key().await;
  108. let validator = validator_account(&client, validator_key).await;
  109. // delete accounts if any to be sure there are no duplicates
  110. drop_created_account(
  111. &client,
  112. validator.account(),
  113. &ALICE_BYTES,
  114. "alice.test.near",
  115. )
  116. .await;
  117. drop_created_account(&client, validator.account(), &BOB_BYTES, "bob.test.near").await;
  118. drop_created_account(&client, validator.account(), &KARL_BYTES, "karl.test.near").await;
  119. drop_created_account(&client, validator.account(), &MIKE_BYTES, "mike.test.near").await;
  120. drop_created_account(
  121. &client,
  122. validator.account(),
  123. &CONTRACT_BYTES,
  124. "contract.test.near",
  125. )
  126. .await;
  127. // create account for key-exchange
  128. // Alice is an initiator account
  129. let alice_sg = create_account(&client, &validator, &ALICE_BYTES, "alice.test.near").await;
  130. let bob_sg = create_account(&client, &validator, &BOB_BYTES, "bob.test.near").await;
  131. let karl_sg = create_account(&client, &validator, &KARL_BYTES, "karl.test.near").await;
  132. let mike_sg = create_account(&client, &validator, &MIKE_BYTES, "mike.test.near").await;
  133. let contract_sg =
  134. create_account(&client, &validator, &CONTRACT_BYTES, "contract.test.near").await;
  135. // Contract byte code
  136. let contract_wasm = meeting_room_contract().await;
  137. let contract_id = contract_sg.account().clone();
  138. client
  139. .deploy_contract(&contract_sg, &contract_id, contract_wasm)
  140. .commit(Finality::Final)
  141. .await
  142. .unwrap();
  143. // config with endpoints
  144. let config = ProvisionerConfig::new(
  145. contract_id.to_string(),
  146. "http://sandbox:3030",
  147. "http://key-exchange:3000",
  148. )
  149. .unwrap();
  150. // Create provisioners for each user
  151. let keypair_str = alice_sg.secret_key().string();
  152. let provisioner = KeyProvisioner::new(
  153. keypair_str,
  154. alice_sg.nonce(),
  155. alice_sg.account().to_string(),
  156. config.clone(),
  157. )
  158. .unwrap();
  159. let arr = JsValue::from(
  160. &[
  161. bob_sg.account().to_string(),
  162. karl_sg.account().to_string(),
  163. mike_sg.account().to_string(),
  164. ]
  165. .into_iter()
  166. .map(|it| JsValue::from_str(&it))
  167. .collect::<js_sys::Array>(),
  168. );
  169. let set = js_sys::Set::new(&arr);
  170. let Meeting { meet_id, .. } = serde_wasm_bindgen::from_value::<Meeting>(
  171. JsFuture::from(provisioner.init_meeting(set, 3000))
  172. .await
  173. .unwrap(),
  174. )
  175. .unwrap();
  176. // Then each user push own key to blockchain
  177. let provisioner_bob = KeyProvisioner::new(
  178. bob_sg.secret_key().string(),
  179. bob_sg.nonce(),
  180. bob_sg.account().to_string(),
  181. config.clone(),
  182. )
  183. .unwrap();
  184. let provisioner_karl = KeyProvisioner::new(
  185. karl_sg.secret_key().string(),
  186. karl_sg.nonce(),
  187. karl_sg.account().to_string(),
  188. config.clone(),
  189. )
  190. .unwrap();
  191. let provisioner_mike = KeyProvisioner::new(
  192. mike_sg.secret_key().string(),
  193. mike_sg.nonce(),
  194. mike_sg.account().to_string(),
  195. config.clone(),
  196. )
  197. .unwrap();
  198. let _ = JsFuture::from(provisioner.send_keys(meet_id.to_string(), 300)).await;
  199. gloo_timers::future::sleep(std::time::Duration::from_millis(400)).await;
  200. let _ = JsFuture::from(provisioner_bob.get_key(meet_id.to_string(), 200)).await;
  201. let _ = JsFuture::from(provisioner_karl.get_key(meet_id.to_string(), 200)).await;
  202. let _ = JsFuture::from(provisioner_mike.get_key(meet_id.to_string(), 200)).await;
  203. // Send encrypted keys to participants
  204. // timeout in millis
  205. let alice_key = JsFuture::from(provisioner.send_keys(meet_id.to_string(), 4000))
  206. .await
  207. .unwrap()
  208. .as_string()
  209. .unwrap();
  210. // Fetch encrypted keys
  211. let bob_key = JsFuture::from(provisioner_bob.get_key(meet_id.to_string(), 1000))
  212. .await
  213. .unwrap()
  214. .as_string()
  215. .unwrap();
  216. let karl_key = JsFuture::from(provisioner_karl.get_key(meet_id.to_string(), 1000))
  217. .await
  218. .unwrap()
  219. .as_string()
  220. .unwrap();
  221. let mike_key = JsFuture::from(provisioner_mike.get_key(meet_id.to_string(), 1000))
  222. .await
  223. .unwrap()
  224. .as_string()
  225. .unwrap();
  226. assert!(&[mike_key, bob_key, karl_key]
  227. .into_iter()
  228. .all(|key| key == alice_key));
  229. // delete all accounts
  230. drop_created_account(
  231. &client,
  232. validator.account(),
  233. &ALICE_BYTES,
  234. "alice.test.near",
  235. )
  236. .await;
  237. drop_created_account(&client, validator.account(), &BOB_BYTES, "bob.test.near").await;
  238. drop_created_account(&client, validator.account(), &KARL_BYTES, "karl.test.near").await;
  239. drop_created_account(&client, validator.account(), &MIKE_BYTES, "mike.test.near").await;
  240. drop_created_account(
  241. &client,
  242. validator.account(),
  243. &CONTRACT_BYTES,
  244. "contract.test.near",
  245. )
  246. .await;
  247. }