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

integration.rs 8.0KB

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