123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- use near_client::{near_primitives_light::views::AccessKeyView, near_units, prelude::*};
- use serde::{Deserialize, Serialize};
- use std::str::FromStr;
- use url::Url;
- use wasm_bindgen::JsValue;
- use wasm_bindgen_futures::JsFuture;
- use wasm_bindgen_test::*;
- use web_client::{KeyProvisioner, Meeting, ProvisionerConfig};
-
- wasm_bindgen_test_configure!(run_in_browser);
-
- const ALICE_BYTES: [u8; 32] = [1; 32];
- const BOB_BYTES: [u8; 32] = [2; 32];
- const KARL_BYTES: [u8; 32] = [3; 32];
- const MIKE_BYTES: [u8; 32] = [4; 32];
- const CONTRACT_BYTES: [u8; 32] = [5; 32];
-
- #[derive(Serialize, Deserialize)]
- struct ValidatorKey {
- account_id: AccountId,
- public_key: Ed25519PublicKey,
- secret_key: String,
- }
-
- async fn create_account(
- client: &NearClient,
- validator: &Signer,
- sk_bytes: &[u8; 32],
- id_str: &str,
- ) -> Signer {
- let id = AccountId::from_str(id_str).unwrap();
- let sk = Ed25519SecretKey::try_from_bytes(sk_bytes).unwrap();
- let pk = Ed25519PublicKey::from(&sk);
-
- let amount = near_units::near::parse("200 N").unwrap();
-
- client
- .create_account(validator, &id, pk, amount)
- .commit(Finality::Final)
- .await
- .unwrap();
-
- let nonce = client
- .view_access_key(&id, &pk, Finality::None)
- .await
- .unwrap()
- .nonce;
-
- Signer::from_secret(sk, id, nonce)
- }
-
- async fn drop_created_account(
- client: &NearClient,
- beneficiary_acc_id: &AccountId,
- sk_bytes: &[u8; 32],
- id_str: &str,
- ) {
- let id = AccountId::from_str(id_str).unwrap();
- let sk = Ed25519SecretKey::try_from_bytes(sk_bytes).unwrap();
- let pk = Ed25519PublicKey::from(&sk);
-
- if let Ok(AccessKeyView { nonce, .. }) = client.view_access_key(&id, &pk, Finality::Final).await
- {
- let signer = Signer::from_secret(sk, id.clone(), nonce);
- signer.update_nonce(nonce);
-
- client
- .delete_account(&signer, &id, beneficiary_acc_id)
- .commit(Finality::Final)
- .await
- .unwrap();
- }
- }
-
- async fn validator_key() -> ValidatorKey {
- reqwest::get("http://sandbox-artifact:3032/validator_key.json")
- .await
- .unwrap()
- .json::<ValidatorKey>()
- .await
- .unwrap()
- }
-
- async fn validator_account(client: &NearClient, validator_key: ValidatorKey) -> Signer {
- let key_nonce = client
- .view_access_key(
- &validator_key.account_id,
- &validator_key.public_key,
- Finality::Final,
- )
- .await
- .unwrap()
- .nonce;
-
- Signer::from_secret_str(
- &validator_key.secret_key,
- validator_key.account_id.clone(),
- key_nonce,
- )
- .unwrap()
- }
-
- async fn meeting_room_contract() -> Vec<u8> {
- reqwest::get("http://contract-artifact:3033/meet.wasm")
- .await
- .unwrap()
- .bytes()
- .await
- .unwrap()
- .to_vec()
- }
-
- #[wasm_bindgen_test]
- async fn key_exchange() {
- let rpc_url = Url::parse("http://sandbox:3030").unwrap();
- let client = NearClient::new(rpc_url).unwrap();
-
- let validator_key = validator_key().await;
- let validator = validator_account(&client, validator_key).await;
-
- // delete accounts if any to be sure there are no duplicates
- drop_created_account(
- &client,
- validator.account(),
- &ALICE_BYTES,
- "alice.test.near",
- )
- .await;
- drop_created_account(&client, validator.account(), &BOB_BYTES, "bob.test.near").await;
- drop_created_account(&client, validator.account(), &KARL_BYTES, "karl.test.near").await;
- drop_created_account(&client, validator.account(), &MIKE_BYTES, "mike.test.near").await;
- drop_created_account(
- &client,
- validator.account(),
- &CONTRACT_BYTES,
- "contract.test.near",
- )
- .await;
-
- // create account for key-exchange
- // Alice is an initiator account
- let alice_sg = create_account(&client, &validator, &ALICE_BYTES, "alice.test.near").await;
- let bob_sg = create_account(&client, &validator, &BOB_BYTES, "bob.test.near").await;
- let karl_sg = create_account(&client, &validator, &KARL_BYTES, "karl.test.near").await;
- let mike_sg = create_account(&client, &validator, &MIKE_BYTES, "mike.test.near").await;
- let contract_sg =
- create_account(&client, &validator, &CONTRACT_BYTES, "contract.test.near").await;
-
- // Contract byte code
- let contract_wasm = meeting_room_contract().await;
- let contract_id = contract_sg.account().clone();
-
- client
- .deploy_contract(&contract_sg, &contract_id, contract_wasm)
- .commit(Finality::Final)
- .await
- .unwrap();
-
- // config with endpoints
- let config = ProvisionerConfig::new(
- contract_id.to_string(),
- "http://sandbox:3030",
- "http://key-exchange:3000",
- )
- .unwrap();
-
- // Create provisioners for each user
- let keypair_str = alice_sg.secret_key().string();
- let provisioner = KeyProvisioner::new(
- keypair_str,
- alice_sg.nonce(),
- alice_sg.account().to_string(),
- config.clone(),
- )
- .unwrap();
-
- let arr = JsValue::from(
- &[
- bob_sg.account().to_string(),
- karl_sg.account().to_string(),
- mike_sg.account().to_string(),
- ]
- .into_iter()
- .map(|it| JsValue::from_str(&it))
- .collect::<js_sys::Array>(),
- );
-
- let set = js_sys::Set::new(&arr);
-
- let Meeting { meet_id, .. } = serde_wasm_bindgen::from_value::<Meeting>(
- JsFuture::from(provisioner.init_meeting(set, 3000))
- .await
- .unwrap(),
- )
- .unwrap();
-
- // Then each user push own key to blockchain
- let provisioner_bob = KeyProvisioner::new(
- bob_sg.secret_key().string(),
- bob_sg.nonce(),
- bob_sg.account().to_string(),
- config.clone(),
- )
- .unwrap();
-
- let provisioner_karl = KeyProvisioner::new(
- karl_sg.secret_key().string(),
- karl_sg.nonce(),
- karl_sg.account().to_string(),
- config.clone(),
- )
- .unwrap();
-
- let provisioner_mike = KeyProvisioner::new(
- mike_sg.secret_key().string(),
- mike_sg.nonce(),
- mike_sg.account().to_string(),
- config.clone(),
- )
- .unwrap();
-
- let _ = JsFuture::from(provisioner.send_keys(meet_id.to_string(), 300)).await;
- gloo_timers::future::sleep(std::time::Duration::from_millis(400)).await;
- let _ = JsFuture::from(provisioner_bob.get_key(meet_id.to_string(), 200)).await;
- let _ = JsFuture::from(provisioner_karl.get_key(meet_id.to_string(), 200)).await;
- let _ = JsFuture::from(provisioner_mike.get_key(meet_id.to_string(), 200)).await;
-
- // Send encrypted keys to participants
- // timeout in millis
- let alice_key = JsFuture::from(provisioner.send_keys(meet_id.to_string(), 4000))
- .await
- .unwrap()
- .as_string()
- .unwrap();
-
- // Fetch encrypted keys
- let bob_key = JsFuture::from(provisioner_bob.get_key(meet_id.to_string(), 1000))
- .await
- .unwrap()
- .as_string()
- .unwrap();
-
- let karl_key = JsFuture::from(provisioner_karl.get_key(meet_id.to_string(), 1000))
- .await
- .unwrap()
- .as_string()
- .unwrap();
-
- let mike_key = JsFuture::from(provisioner_mike.get_key(meet_id.to_string(), 1000))
- .await
- .unwrap()
- .as_string()
- .unwrap();
-
- assert!(&[mike_key, bob_key, karl_key]
- .into_iter()
- .all(|key| key == alice_key));
-
- // delete all accounts
- drop_created_account(
- &client,
- validator.account(),
- &ALICE_BYTES,
- "alice.test.near",
- )
- .await;
- drop_created_account(&client, validator.account(), &BOB_BYTES, "bob.test.near").await;
- drop_created_account(&client, validator.account(), &KARL_BYTES, "karl.test.near").await;
- drop_created_account(&client, validator.account(), &MIKE_BYTES, "mike.test.near").await;
- drop_created_account(
- &client,
- validator.account(),
- &CONTRACT_BYTES,
- "contract.test.near",
- )
- .await;
- }
|