You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

integration.rs 7.9KB

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