Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

integration.rs 8.4KB

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