From 49ad3009c32e14dac925d64055abfacd90528cce Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 16:36:38 -0700 Subject: [PATCH 01/11] add log to verify state() hangs --- chain-signatures/node/src/mesh/connection.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/chain-signatures/node/src/mesh/connection.rs b/chain-signatures/node/src/mesh/connection.rs index ef6029ac3..4096b72a2 100644 --- a/chain-signatures/node/src/mesh/connection.rs +++ b/chain-signatures/node/src/mesh/connection.rs @@ -49,7 +49,17 @@ impl Pool { continue; }; + tracing::debug!( + "going to send /state call to {:?} url {} /state", + participant, + info.url + ); let Ok(resp) = self.http.get(url.clone()).send().await else { + tracing::debug!( + "finish send /state call to {:?} url {} /state", + participant, + info.url + ); tracing::warn!( "Pool.ping resp err participant {:?} url {}", participant, @@ -58,6 +68,12 @@ impl Pool { continue; }; + tracing::debug!( + "finish send /state call to {:?} url {} /state", + participant, + info.url + ); + let Ok(state): Result = resp.json().await else { tracing::warn!( "Pool.ping state view err participant {:?} url {}", From 7ae09922627f1e7b0868f8f919ca33993998998e Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 17:18:35 -0700 Subject: [PATCH 02/11] more logs --- chain-signatures/node/src/protocol/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chain-signatures/node/src/protocol/mod.rs b/chain-signatures/node/src/protocol/mod.rs index 73cea146e..954f6d2e6 100644 --- a/chain-signatures/node/src/protocol/mod.rs +++ b/chain-signatures/node/src/protocol/mod.rs @@ -284,10 +284,13 @@ impl MpcSignProtocol { } if last_pinged.elapsed() > Duration::from_millis(300) { + tracing::debug!("doing ping now"); self.ctx.mesh.ping().await; last_pinged = Instant::now(); } + tracing::debug!("finish ping now"); + let state = { let guard = self.state.read().await; guard.clone() From 0799a1e07f10804540b73045dc059c3cbe9484ea Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 17:19:50 -0700 Subject: [PATCH 03/11] more logs --- chain-signatures/node/src/protocol/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/chain-signatures/node/src/protocol/mod.rs b/chain-signatures/node/src/protocol/mod.rs index 954f6d2e6..34b134f51 100644 --- a/chain-signatures/node/src/protocol/mod.rs +++ b/chain-signatures/node/src/protocol/mod.rs @@ -296,6 +296,7 @@ impl MpcSignProtocol { guard.clone() }; + tracing::debug!("finish reading state now"); let crypto_time = Instant::now(); let mut state = match state.progress(&mut self).await { Ok(state) => { From 75186f7575a99b8e73c30b2537cab3fbfbf2f244 Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 17:24:00 -0700 Subject: [PATCH 04/11] log ping latency --- chain-signatures/node/src/protocol/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chain-signatures/node/src/protocol/mod.rs b/chain-signatures/node/src/protocol/mod.rs index 34b134f51..ea1cd5455 100644 --- a/chain-signatures/node/src/protocol/mod.rs +++ b/chain-signatures/node/src/protocol/mod.rs @@ -285,7 +285,10 @@ impl MpcSignProtocol { if last_pinged.elapsed() > Duration::from_millis(300) { tracing::debug!("doing ping now"); + let start = Instant::now(); self.ctx.mesh.ping().await; + let ping_latency = start.elapsed().as_secs(); + tracing::debug!("ping latency was {ping_latency} seconds"); last_pinged = Instant::now(); } From e1739f521bf14cdc53be76b3c5583fac0386b234 Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 17:51:25 -0700 Subject: [PATCH 05/11] add timeout to requests --- chain-signatures/node/src/cli.rs | 2 ++ chain-signatures/node/src/http_client.rs | 1 + chain-signatures/node/src/mesh/connection.rs | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/chain-signatures/node/src/cli.rs b/chain-signatures/node/src/cli.rs index c47d86604..c74f2b23c 100644 --- a/chain-signatures/node/src/cli.rs +++ b/chain-signatures/node/src/cli.rs @@ -8,6 +8,7 @@ use local_ip_address::local_ip; use near_account_id::AccountId; use near_crypto::{InMemorySigner, SecretKey}; use std::sync::Arc; +use std::time::Duration; use tokio::sync::{mpsc, RwLock}; use tracing_stackdriver::layer as stackdriver_layer; use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; @@ -135,6 +136,7 @@ fn is_running_on_gcp() -> bool { let resp = reqwest::blocking::Client::new() .get("http://metadata.google.internal/computeMetadata/v1/instance/id") .header("Metadata-Flavor", "Google") + .timeout(Duration::from_secs(1)) .send(); match resp { diff --git a/chain-signatures/node/src/http_client.rs b/chain-signatures/node/src/http_client.rs index 40a80a5a9..17d7253db 100644 --- a/chain-signatures/node/src/http_client.rs +++ b/chain-signatures/node/src/http_client.rs @@ -46,6 +46,7 @@ async fn send_encrypted( .post(url.clone()) .header("content-type", "application/json") .json(&message) + .timeout(Duration::from_secs(1)) .send() .await .map_err(SendError::ReqwestClientError)?; diff --git a/chain-signatures/node/src/mesh/connection.rs b/chain-signatures/node/src/mesh/connection.rs index 4096b72a2..17c751d76 100644 --- a/chain-signatures/node/src/mesh/connection.rs +++ b/chain-signatures/node/src/mesh/connection.rs @@ -54,7 +54,7 @@ impl Pool { participant, info.url ); - let Ok(resp) = self.http.get(url.clone()).send().await else { + let Ok(resp) = self.http.get(url.clone()).timeout(Duration::from_secs(1)).send().await else { tracing::debug!( "finish send /state call to {:?} url {} /state", participant, @@ -109,7 +109,7 @@ impl Pool { continue; }; - let Ok(resp) = self.http.get(url).send().await else { + let Ok(resp) = self.http.get(url).timeout(Duration::from_secs(1)).send().await else { continue; }; From 7fe23d1e67da0aec8955aa6339deebef1cb6c62f Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 17:52:29 -0700 Subject: [PATCH 06/11] increase timeout --- chain-signatures/node/src/http_client.rs | 2 +- chain-signatures/node/src/mesh/connection.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chain-signatures/node/src/http_client.rs b/chain-signatures/node/src/http_client.rs index 17d7253db..406db32f9 100644 --- a/chain-signatures/node/src/http_client.rs +++ b/chain-signatures/node/src/http_client.rs @@ -46,7 +46,7 @@ async fn send_encrypted( .post(url.clone()) .header("content-type", "application/json") .json(&message) - .timeout(Duration::from_secs(1)) + .timeout(Duration::from_secs(5)) .send() .await .map_err(SendError::ReqwestClientError)?; diff --git a/chain-signatures/node/src/mesh/connection.rs b/chain-signatures/node/src/mesh/connection.rs index 17c751d76..20a578eb9 100644 --- a/chain-signatures/node/src/mesh/connection.rs +++ b/chain-signatures/node/src/mesh/connection.rs @@ -54,7 +54,7 @@ impl Pool { participant, info.url ); - let Ok(resp) = self.http.get(url.clone()).timeout(Duration::from_secs(1)).send().await else { + let Ok(resp) = self.http.get(url.clone()).timeout(Duration::from_secs(2)).send().await else { tracing::debug!( "finish send /state call to {:?} url {} /state", participant, @@ -109,7 +109,7 @@ impl Pool { continue; }; - let Ok(resp) = self.http.get(url).timeout(Duration::from_secs(1)).send().await else { + let Ok(resp) = self.http.get(url).timeout(Duration::from_secs(2)).send().await else { continue; }; From 2eb8859d699146dc8259b223130d4f2bdf3361d8 Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 18:45:57 -0700 Subject: [PATCH 07/11] add counter of iter at start of loop --- chain-signatures/node/src/metrics.rs | 9 +++++++++ chain-signatures/node/src/protocol/mod.rs | 3 +++ 2 files changed, 12 insertions(+) diff --git a/chain-signatures/node/src/metrics.rs b/chain-signatures/node/src/metrics.rs index ed36d4547..ea7f14f90 100644 --- a/chain-signatures/node/src/metrics.rs +++ b/chain-signatures/node/src/metrics.rs @@ -389,6 +389,15 @@ pub(crate) static SIGNATURE_PUBLISH_FAILURES: Lazy = Lazy::new(|| { .unwrap() }); +pub(crate) static PROTOCOL_LATENCY_ITER_CNT: Lazy = Lazy::new(|| { + try_create_counter_vec( + "multichain_protocol_iter_count", + "Count of multichain protocol iter", + &["node_account_id"], + ) + .unwrap() +}); + pub(crate) static SIGNATURE_PUBLISH_RESPONSE_ERRORS: Lazy = Lazy::new(|| { try_create_counter_vec( "multichain_signature_publish_response_errors", diff --git a/chain-signatures/node/src/protocol/mod.rs b/chain-signatures/node/src/protocol/mod.rs index ea1cd5455..5ff7f8826 100644 --- a/chain-signatures/node/src/protocol/mod.rs +++ b/chain-signatures/node/src/protocol/mod.rs @@ -227,6 +227,9 @@ impl MpcSignProtocol { loop { let protocol_time = Instant::now(); tracing::debug!("trying to advance chain signatures protocol"); + crate::metrics::PROTOCOL_LATENCY_ITER_CNT + .with_label_values(&[my_account_id.as_str()]) + .inc(); loop { let msg_result = self.receiver.try_recv(); match msg_result { From 0bece6223b0cee648b1dba014a0ed69f03753d45 Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Wed, 9 Oct 2024 18:50:40 -0700 Subject: [PATCH 08/11] remove logging and add metric --- chain-signatures/node/src/mesh/connection.rs | 32 +++++++++----------- chain-signatures/node/src/metrics.rs | 12 ++++---- chain-signatures/node/src/protocol/mod.rs | 8 +---- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/chain-signatures/node/src/mesh/connection.rs b/chain-signatures/node/src/mesh/connection.rs index 20a578eb9..12098eeb8 100644 --- a/chain-signatures/node/src/mesh/connection.rs +++ b/chain-signatures/node/src/mesh/connection.rs @@ -49,17 +49,13 @@ impl Pool { continue; }; - tracing::debug!( - "going to send /state call to {:?} url {} /state", - participant, - info.url - ); - let Ok(resp) = self.http.get(url.clone()).timeout(Duration::from_secs(2)).send().await else { - tracing::debug!( - "finish send /state call to {:?} url {} /state", - participant, - info.url - ); + let Ok(resp) = self + .http + .get(url.clone()) + .timeout(Duration::from_secs(2)) + .send() + .await + else { tracing::warn!( "Pool.ping resp err participant {:?} url {}", participant, @@ -68,12 +64,6 @@ impl Pool { continue; }; - tracing::debug!( - "finish send /state call to {:?} url {} /state", - participant, - info.url - ); - let Ok(state): Result = resp.json().await else { tracing::warn!( "Pool.ping state view err participant {:?} url {}", @@ -109,7 +99,13 @@ impl Pool { continue; }; - let Ok(resp) = self.http.get(url).timeout(Duration::from_secs(2)).send().await else { + let Ok(resp) = self + .http + .get(url) + .timeout(Duration::from_secs(2)) + .send() + .await + else { continue; }; diff --git a/chain-signatures/node/src/metrics.rs b/chain-signatures/node/src/metrics.rs index ea7f14f90..57e71afce 100644 --- a/chain-signatures/node/src/metrics.rs +++ b/chain-signatures/node/src/metrics.rs @@ -389,19 +389,19 @@ pub(crate) static SIGNATURE_PUBLISH_FAILURES: Lazy = Lazy::new(|| { .unwrap() }); -pub(crate) static PROTOCOL_LATENCY_ITER_CNT: Lazy = Lazy::new(|| { +pub(crate) static SIGNATURE_PUBLISH_RESPONSE_ERRORS: Lazy = Lazy::new(|| { try_create_counter_vec( - "multichain_protocol_iter_count", - "Count of multichain protocol iter", + "multichain_signature_publish_response_errors", + "number of respond calls with response that cannot be converted to json", &["node_account_id"], ) .unwrap() }); -pub(crate) static SIGNATURE_PUBLISH_RESPONSE_ERRORS: Lazy = Lazy::new(|| { +pub(crate) static PROTOCOL_LATENCY_ITER_CNT: Lazy = Lazy::new(|| { try_create_counter_vec( - "multichain_signature_publish_response_errors", - "number of respond calls with response that cannot be converted to json", + "multichain_protocol_iter_count", + "Count of multichain protocol iter", &["node_account_id"], ) .unwrap() diff --git a/chain-signatures/node/src/protocol/mod.rs b/chain-signatures/node/src/protocol/mod.rs index 5ff7f8826..33fb58c50 100644 --- a/chain-signatures/node/src/protocol/mod.rs +++ b/chain-signatures/node/src/protocol/mod.rs @@ -230,6 +230,7 @@ impl MpcSignProtocol { crate::metrics::PROTOCOL_LATENCY_ITER_CNT .with_label_values(&[my_account_id.as_str()]) .inc(); + loop { let msg_result = self.receiver.try_recv(); match msg_result { @@ -287,22 +288,15 @@ impl MpcSignProtocol { } if last_pinged.elapsed() > Duration::from_millis(300) { - tracing::debug!("doing ping now"); - let start = Instant::now(); self.ctx.mesh.ping().await; - let ping_latency = start.elapsed().as_secs(); - tracing::debug!("ping latency was {ping_latency} seconds"); last_pinged = Instant::now(); } - tracing::debug!("finish ping now"); - let state = { let guard = self.state.read().await; guard.clone() }; - tracing::debug!("finish reading state now"); let crypto_time = Instant::now(); let mut state = match state.progress(&mut self).await { Ok(state) => { From b70a537ee84ccc656bf08b04d680edbc87498b3c Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Thu, 10 Oct 2024 10:17:32 -0700 Subject: [PATCH 09/11] change name --- chain-signatures/node/src/metrics.rs | 2 +- chain-signatures/node/src/protocol/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/chain-signatures/node/src/metrics.rs b/chain-signatures/node/src/metrics.rs index 57e71afce..b5f388171 100644 --- a/chain-signatures/node/src/metrics.rs +++ b/chain-signatures/node/src/metrics.rs @@ -398,7 +398,7 @@ pub(crate) static SIGNATURE_PUBLISH_RESPONSE_ERRORS: Lazy = Lazy::ne .unwrap() }); -pub(crate) static PROTOCOL_LATENCY_ITER_CNT: Lazy = Lazy::new(|| { +pub(crate) static PROTOCOL_ITER_CNT: Lazy = Lazy::new(|| { try_create_counter_vec( "multichain_protocol_iter_count", "Count of multichain protocol iter", diff --git a/chain-signatures/node/src/protocol/mod.rs b/chain-signatures/node/src/protocol/mod.rs index 33fb58c50..6960364c3 100644 --- a/chain-signatures/node/src/protocol/mod.rs +++ b/chain-signatures/node/src/protocol/mod.rs @@ -227,7 +227,7 @@ impl MpcSignProtocol { loop { let protocol_time = Instant::now(); tracing::debug!("trying to advance chain signatures protocol"); - crate::metrics::PROTOCOL_LATENCY_ITER_CNT + crate::metrics::PROTOCOL_ITER_CNT .with_label_values(&[my_account_id.as_str()]) .inc(); From d798f96f70a2800f7ff3f43901075236100a5ca2 Mon Sep 17 00:00:00 2001 From: Xiangyi Zheng Date: Thu, 10 Oct 2024 10:32:02 -0700 Subject: [PATCH 10/11] lower timeout --- chain-signatures/node/src/http_client.rs | 2 +- chain-signatures/node/src/mesh/connection.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chain-signatures/node/src/http_client.rs b/chain-signatures/node/src/http_client.rs index 406db32f9..147392bc8 100644 --- a/chain-signatures/node/src/http_client.rs +++ b/chain-signatures/node/src/http_client.rs @@ -46,7 +46,7 @@ async fn send_encrypted( .post(url.clone()) .header("content-type", "application/json") .json(&message) - .timeout(Duration::from_secs(5)) + .timeout(Duration::from_secs(2)) .send() .await .map_err(SendError::ReqwestClientError)?; diff --git a/chain-signatures/node/src/mesh/connection.rs b/chain-signatures/node/src/mesh/connection.rs index 12098eeb8..4367102f1 100644 --- a/chain-signatures/node/src/mesh/connection.rs +++ b/chain-signatures/node/src/mesh/connection.rs @@ -52,7 +52,7 @@ impl Pool { let Ok(resp) = self .http .get(url.clone()) - .timeout(Duration::from_secs(2)) + .timeout(Duration::from_secs(1)) .send() .await else { @@ -102,7 +102,7 @@ impl Pool { let Ok(resp) = self .http .get(url) - .timeout(Duration::from_secs(2)) + .timeout(Duration::from_secs(1)) .send() .await else { From b0a09ec3bb3a9098a10e37f146f4cdcab4361b4b Mon Sep 17 00:00:00 2001 From: Serhii Volovyk Date: Thu, 10 Oct 2024 20:57:56 +0300 Subject: [PATCH 11/11] README files rearenged, updated, and expanded (#878) --- chain-signatures/README.md => API.md | 6 +----- ARCHITECTURE.md | 10 ---------- README.md | 22 +++++++--------------- ROADMAP.md | 17 +++++++++++++++++ SCALING_AND_SECURITY.md | 5 +++++ mpc-recovery/README.md | 5 ++++- 6 files changed, 34 insertions(+), 31 deletions(-) rename chain-signatures/README.md => API.md (91%) create mode 100644 ROADMAP.md create mode 100644 SCALING_AND_SECURITY.md diff --git a/chain-signatures/README.md b/API.md similarity index 91% rename from chain-signatures/README.md rename to API.md index e0f20cc50..5e88de201 100644 --- a/chain-signatures/README.md +++ b/API.md @@ -54,9 +54,5 @@ pub fn experimantal_signature_deposit(&self) -> u128 For more details check `User contract API` impl block in the [chain-signatures/contracts/src/lib.rs](./chain-signatures/contracts/src/lib.rs) file. # Environments -Currently, we have 3 environments: 1. Mainnet: `v1.signer` -2. Testnet: `v1.sigenr-prod.testnet` -3. Dev (unstable): `v1.signer-dev.testnet` - -Contracts can be changed from v1 to v2, etc. Older contracts should continue functioning. \ No newline at end of file +2. Testnet: `v1.sigenr-prod.testnet` \ No newline at end of file diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 952a9bf65..e9e9e1334 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,15 +1,5 @@ # Architecture -This doc outlines the architecture for NEAR's Multi-Party Computation (MPC) related services which powers FastAuth and Chain Signatures. - -## FastAuth (aka mpc-recovery) - -FastAuth allows a user to store their login details for their NEAR wallet in a set amount of MPC nodes. Each node contains a share of the user's credentials. Note, this will likely change in the future as we resdesign the system to utilize chain signatures instead of having to purely rely on a standalone MPC service for NEAR accounts. - -## Chain Signatures - -Chain signature is an MPC service that facilitates the ability to sign arbitrary payloads by calling into a smart contract and eventually getting back a signature. This signature can be used for various purposes such as deriving new public keys associated to foreign chains. - There are several components that make up chain-signatures. This includes but is not limited to the following: - NEAR Smart Contract diff --git a/README.md b/README.md index 20726471c..f01be59ca 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,11 @@ -# NEAR MPC - -This repo hosts all the code for MPC related services on NEAR, which includes but is not limited to FastAuth and Chain Signatures. - - ## Chain Signatures -An MPC service that generates signatures based on a payload. These are a set of N nodes operating as a sort of L2 (maybe L0) where users (developers or clients) can talk to a smart contract on NEAR to generate a signature. This signature can then be used for multiple purposes such as managing an account located on a foreign chain (BTC, ETH, ...) - -Most of this code is located in `chain-signatures/` folder and for more information on how most of this work or its design, refer to [ARCHITECTURE.md](ARCHITECTURE.md). - -## FastAuth (aka MPC recovery) - -An MPC service that allows users to create NEAR accounts based on an identity provider. The secret key belonging to these accounts are stored partially on an MPC node, where the full key is never recreated. For more info on, look at the [mpc-recovery/README.md](mpc-recovery/README.md) +Chain signatures is an MPC service that facilitates the ability to sign arbitrary payloads by calling into a smart contract and eventually getting back a signature. This signature can be used for various purposes such as deriving new public keys associated to foreign chains (Ethereum, Bitcoin, etc.). -## Notes +### More inforamtion: +- [API](API.md) +- [Roadmap](ROADMAP.md) +- [Architecure](ARCHITECTURE.md) +- [Scaling and Security](SCALING_AND_SECURITY.md) -- Not to be confused, but FastAuth and Chain Signatures are separate services. This can change in the future but they remain separate for now. -- FastAuth also has an equivalent [UI repo](https://github.com/near/fast-auth-signer) which is used in [near.org](near.org) +If you are looking for FastAuth project, please check the [mpc-recovery](/mpc-recovery) folder. diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 000000000..205aa9ce0 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,17 @@ +## Roadmap +### Q4 2024 +- Scale system to 10 nodes (12 on testnet) +- Chain Signatures on Ethereum testnet +- Publish Triple Security Proof +- Publish ECDSA Signature Security Proof + +### Q1 2025 +- Chain Signatures on Ethereum mainnet +- Tooling for NEAR <-> Ethereum smart contract interactions +- EDDSA signatures support +- Scaling of signature production +- Formalize state and message passing w proofs + +### Q2 2025 +- Deploy Chain Signatures on 6+ networks on Testnet +- Release a tooling that allows a NEAR smart contract to call smart contracts on these networks diff --git a/SCALING_AND_SECURITY.md b/SCALING_AND_SECURITY.md new file mode 100644 index 000000000..c89382d91 --- /dev/null +++ b/SCALING_AND_SECURITY.md @@ -0,0 +1,5 @@ +## Scaling capabilities +Currently chain signatures operates using one signature genertion network and can handle up to 8 concurent requests. Average response time is 15 seconds. We are planning to improve both metrics and scale the system to multiple networks wich will allow to handle more requests and reduce response time. + +## Security properties +Chain signatures is usign cait-sith threshold ECDSA protocol. Currently our network consist of 8 nodes with treshold 5. This means that at least 5 nodes must collaborate in order to create a valid signature. \ No newline at end of file diff --git a/mpc-recovery/README.md b/mpc-recovery/README.md index 7ab0ce9c3..4b0784d4a 100644 --- a/mpc-recovery/README.md +++ b/mpc-recovery/README.md @@ -1,4 +1,7 @@ -# MPC Account Recovery (WIP) +## FastAuth (aka mpc-recovery) + +FastAuth allows a user to store their login details for their NEAR wallet in a set amount of MPC nodes. Each node contains a share of the user's credentials. Note, this will likely change in the future as we resdesign the system to utilize chain signatures instead of having to purely rely on a standalone MPC service for NEAR accounts. + The aim of this project is to offer NEAR users the opportunity to create and restore their accounts by utilizing OIDC protocol. By linking their NEAR account to `near.org` or other authentication provider, they can then add a new Full Access key, which will be managed by the trusted network of servers. Should they lose all the keys they possess, they can reauthorize themselves, create a new key, and add it into their NEAR account using a transaction that will be signed by MPC servers through their recovery key. All the transaction cost will be covered by a relayer server and metatransactions. ## How the MPC system will work