Browse Source

Use near-client from crates.io

develop
Silvestr Predko 1 year ago
parent
commit
0f0eb936c4

+ 3
- 25
.github/workflows/ci.yml View File

@@ -39,8 +39,8 @@ jobs:
39 39
           components: clippy
40 40
       - name: cargo clippy
41 41
         run: cargo +nightly clippy --workspace --tests -- -D warnings
42
-  tests-common-api:
43
-    name: tests-common-api
42
+  tests:
43
+    name: tests
44 44
     needs: [clippy, fmt]
45 45
     runs-on: ubuntu-latest
46 46
     steps:
@@ -50,34 +50,12 @@ jobs:
50 50
         with:
51 51
           toolchain: stable
52 52
       - name: Run tests for [common-api]
53
-        run: cargo test -p common-api --tests --all-features
54
-  tests-near:
55
-    name: tests-near
56
-    needs: [clippy, fmt]
57
-    runs-on: ubuntu-latest
58
-    steps:
59
-      - uses: actions/checkout@v3
60
-      - name: Install Rust Toolchain
61
-        uses: actions-rs/toolchain@v1
62
-        with:
63
-          toolchain: stable
64
-          target: wasm32-unknown-unknown
65
-      - name: Setup ssh access for a private repositories
66
-        uses: webfactory/ssh-agent@v0.7.0
67
-        with:
68
-          ssh-private-key: |
69
-            ${{ secrets.CLIENT_SSH_PRIVATE_KEY }}
70
-            ${{ secrets.SMARTCONTRACTS_SSH_PRIVATE_KEY }}
71
-      - name: Run tests for [near-rpc]
72
-        env:
73
-          CARGO_NET_GIT_FETCH_WITH_CLI: true
74
-        run: cargo test -p near-rpc --tests
53
+        run: cargo test --tests --all-features
75 54
   tests-web:
76 55
     name: tests-web
77 56
     needs: [clippy, fmt]
78 57
     runs-on: ubuntu-latest
79 58
     permissions:
80
-      contents: write
81 59
       packages: read
82 60
     steps:
83 61
       - name: Log in to the Container registry

+ 1
- 1
Cargo.toml View File

@@ -1,5 +1,5 @@
1 1
 [workspace]
2
-members = ["web-client", "near-rpc", "common-api", "near-primitives-light"]
2
+members = ["web-client", "common-api"]
3 3
 
4 4
 [profile.release]
5 5
 codegen-units = 1

+ 0
- 2
Dockerfile View File

@@ -2,9 +2,7 @@ FROM rust:latest
2 2
 
3 3
 # Copy a source code
4 4
 COPY web-client /build/web-client
5
-COPY near-rpc /build/near-rpc
6 5
 COPY common-api /build/common-api
7
-COPY near-primitives-light /build/near-primitives-light
8 6
 
9 7
 WORKDIR /build/web-client
10 8
 

+ 2
- 15
common-api/Cargo.toml View File

@@ -9,24 +9,11 @@ API for signing data and shared types. Please note that all data
9 9
 structures should be serializable with "serde" and "borsh"
10 10
 """
11 11
 
12
-[features]
13
-default = ["headers", "api"]
14
-headers = ["dep:near-account-id"]
15
-api = ["dep:near-account-id", "dep:uuid"]
16
-
17 12
 [dependencies]
18
-bs58 = "0.4"
19 13
 borsh = "0.9"
20
-curve25519-dalek = "3"
21
-ed25519-dalek = "1"
22
-itertools = "0.10"
23
-near-account-id = { version = "0.15", optional = true }
14
+near-account-id = { version = "0.15" }
15
+near-client = "0.1"
24 16
 serde = { version = "1", default-features = false, features = ["derive"] }
25
-thiserror = "1"
26
-uuid = { version = "1", optional = true }
27
-x25519-dalek = { version = "1", features = ["serde"] }
28 17
 
29 18
 [dev-dependencies]
30
-rand = "0.8.5"
31
-rand_chacha = "0.3"
32 19
 serde_json = "1"

+ 1
- 1
common-api/src/api.rs View File

@@ -1,6 +1,6 @@
1
-use crate::crypto::prelude::*;
2 1
 use borsh::{BorshDeserialize, BorshSerialize};
3 2
 use near_account_id::AccountId;
3
+use near_client::crypto::prelude::*;
4 4
 use serde::{Deserialize, Serialize};
5 5
 use std::{collections::HashSet, time::Duration};
6 6
 

+ 0
- 305
common-api/src/crypto/ed25519.rs View File

@@ -1,305 +0,0 @@
1
-//! ### Sign with ed25519 elliptic curve signing algorithm
2
-//! ---
3
-//! Used Dalek cryptography, and implemented [`Borsh`](https://borsh.io/) serialization for them
4
-
5
-use borsh::{BorshDeserialize, BorshSerialize};
6
-use ed25519_dalek::{ExpandedSecretKey, PublicKey, SecretKey, Signature, Verifier};
7
-use itertools::Itertools;
8
-use serde::{Deserialize, Serialize};
9
-use std::{
10
-    fmt::Display,
11
-    hash::{Hash, Hasher},
12
-    io::{Error as IoError, ErrorKind},
13
-    str::FromStr,
14
-};
15
-
16
-use super::{split_encoded_str, Error, Key, Result, ED25519};
17
-
18
-pub use ed25519_dalek::{
19
-    KEYPAIR_LENGTH as ED25519_KEYPAIR_LENGTH, PUBLIC_KEY_LENGTH as ED25519_PUBLIC_KEY_LENGTH,
20
-    SECRET_KEY_LENGTH as ED25519_SECRET_KEY_LENGTH, SIGNATURE_LENGTH as ED25519_SIGNATURE_LENGTH,
21
-};
22
-
23
-#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
24
-pub struct Ed25519PublicKey(PublicKey);
25
-
26
-impl Ed25519PublicKey {
27
-    /// Verifies the signature of a signed data
28
-    pub fn verify(&self, data: &[u8], signature: &Ed25519Signature) -> Result<()> {
29
-        self.0
30
-            .verify(data, &signature.0)
31
-            .map_err(|_| Error::Verification(signature.string()))
32
-    }
33
-
34
-    #[inline]
35
-    pub fn as_bytes(&self) -> &[u8; ED25519_PUBLIC_KEY_LENGTH] {
36
-        self.0.as_bytes()
37
-    }
38
-}
39
-
40
-impl Key<ED25519_PUBLIC_KEY_LENGTH> for Ed25519PublicKey {
41
-    const KEY_TYPE: &'static str = ED25519;
42
-
43
-    #[inline]
44
-    fn to_bytes(&self) -> [u8; ED25519_PUBLIC_KEY_LENGTH] {
45
-        self.0.to_bytes()
46
-    }
47
-
48
-    fn try_from_bytes(buf: &[u8]) -> Result<Self> {
49
-        PublicKey::from_bytes(buf)
50
-            .map(Self)
51
-            .map_err(|err| Error::from_bytes::<Ed25519PublicKey>(buf, err.to_string()))
52
-    }
53
-}
54
-
55
-impl BorshDeserialize for Ed25519PublicKey {
56
-    fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
57
-        // The first byte is a key type, let's skip it because currently is used ed25519 only
58
-        // This implementation of [`Ed25519PublicKey`] is required by Near protocol
59
-        let temp_buf = std::mem::take(buf)
60
-            .split_first()
61
-            .map(|(.., key)| key)
62
-            .unwrap_or_default();
63
-        Ed25519PublicKey::try_from_bytes(temp_buf)
64
-            .map_err(|err| IoError::new(ErrorKind::InvalidData, err))
65
-    }
66
-}
67
-
68
-impl BorshSerialize for Ed25519PublicKey {
69
-    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
70
-        BorshSerialize::serialize(&0_u8, writer)?;
71
-        writer.write_all(self.0.as_bytes())
72
-    }
73
-}
74
-
75
-impl From<&Ed25519SecretKey> for Ed25519PublicKey {
76
-    fn from(sk: &Ed25519SecretKey) -> Self {
77
-        Self(PublicKey::from(&sk.0))
78
-    }
79
-}
80
-
81
-// This `Hash` implementation is safe since it retains the property
82
-// `k1 == k2 ⇒ hash(k1) == hash(k2)`.
83
-#[allow(clippy::derived_hash_with_manual_eq)]
84
-impl Hash for Ed25519PublicKey {
85
-    fn hash<H: Hasher>(&self, state: &mut H) {
86
-        state.write_u8(0u8);
87
-        state.write(self.0.as_bytes());
88
-    }
89
-}
90
-
91
-impl Display for Ed25519PublicKey {
92
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93
-        write!(f, "{}", self.string())
94
-    }
95
-}
96
-
97
-pub struct Ed25519SecretKey(SecretKey);
98
-
99
-impl Ed25519SecretKey {
100
-    /// Sign a `data` with a private key
101
-    pub fn sign(&self, data: &[u8], public_key: &Ed25519PublicKey) -> Ed25519Signature {
102
-        let expanded_key = ExpandedSecretKey::from(&self.0);
103
-        Ed25519Signature(expanded_key.sign(data, &public_key.0))
104
-    }
105
-
106
-    /// Near protocol using expanded secret key
107
-    pub fn from_expanded(key: &str) -> Result<Self> {
108
-        let (key_type, bs58_encoded) = split_encoded_str(key)?;
109
-
110
-        if key_type != Self::KEY_TYPE {
111
-            return Err(Error::WrongKeyType {
112
-                key_type: key_type.to_owned(),
113
-                expected_key_type: Self::KEY_TYPE,
114
-            });
115
-        }
116
-
117
-        let expanded_key_bytes = bs58::decode(bs58_encoded)
118
-            .into_vec()
119
-            .map_err(|err| {
120
-                Error::from_string::<Ed25519SecretKey>(bs58_encoded.to_owned(), err.to_string())
121
-            })?
122
-            .into_iter()
123
-            .take(ED25519_SECRET_KEY_LENGTH)
124
-            .collect_vec();
125
-        Self::try_from_bytes(&expanded_key_bytes)
126
-    }
127
-
128
-    #[inline]
129
-    pub fn as_bytes(&self) -> &[u8; ED25519_PUBLIC_KEY_LENGTH] {
130
-        self.0.as_bytes()
131
-    }
132
-}
133
-
134
-impl Key<ED25519_SECRET_KEY_LENGTH> for Ed25519SecretKey {
135
-    const KEY_TYPE: &'static str = ED25519;
136
-
137
-    #[inline]
138
-    fn to_bytes(&self) -> [u8; ED25519_SECRET_KEY_LENGTH] {
139
-        self.0.to_bytes()
140
-    }
141
-
142
-    fn try_from_bytes(buf: &[u8]) -> Result<Self> {
143
-        SecretKey::from_bytes(buf)
144
-            .map(Self)
145
-            .map_err(|err| Error::from_bytes::<Ed25519SecretKey>(buf, err.to_string()))
146
-    }
147
-}
148
-
149
-impl BorshDeserialize for Ed25519SecretKey {
150
-    fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
151
-        Ed25519SecretKey::try_from_bytes(std::mem::take(buf))
152
-            .map_err(|err| IoError::new(ErrorKind::InvalidData, err))
153
-    }
154
-}
155
-
156
-impl BorshSerialize for Ed25519SecretKey {
157
-    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
158
-        writer.write_all(self.0.as_bytes())
159
-    }
160
-}
161
-
162
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
163
-pub struct Ed25519Signature(Signature);
164
-
165
-impl Key<ED25519_SIGNATURE_LENGTH> for Ed25519Signature {
166
-    const KEY_TYPE: &'static str = ED25519;
167
-
168
-    #[inline]
169
-    fn to_bytes(&self) -> [u8; ED25519_SIGNATURE_LENGTH] {
170
-        self.0.to_bytes()
171
-    }
172
-
173
-    fn try_from_bytes(buf: &[u8]) -> Result<Self> {
174
-        Signature::from_bytes(buf)
175
-            .map(Self)
176
-            .map_err(|err| Error::from_bytes::<Ed25519Signature>(buf, err.to_string()))
177
-    }
178
-}
179
-
180
-impl BorshDeserialize for Ed25519Signature {
181
-    fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
182
-        // The first byte is a key type, let's skip it because currently is used ed25519 only
183
-        // This implementation of [`Ed25519Signature`] is required by Near protocol
184
-        let temp_buf = std::mem::take(buf)
185
-            .split_first()
186
-            .map(|(.., key)| key)
187
-            .unwrap_or_default();
188
-        Ed25519Signature::try_from_bytes(temp_buf)
189
-            .map_err(|err| IoError::new(ErrorKind::InvalidData, err))
190
-    }
191
-}
192
-
193
-impl BorshSerialize for Ed25519Signature {
194
-    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
195
-        BorshSerialize::serialize(&0_u8, writer)?;
196
-        writer.write_all(&self.0.to_bytes())
197
-    }
198
-}
199
-
200
-#[allow(clippy::derived_hash_with_manual_eq)]
201
-impl Hash for Ed25519Signature {
202
-    fn hash<H: Hasher>(&self, state: &mut H) {
203
-        self.to_bytes().hash(state);
204
-    }
205
-}
206
-
207
-impl Display for Ed25519Signature {
208
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209
-        write!(f, "{}", self.string())
210
-    }
211
-}
212
-
213
-/// Contains public and secret user keys
214
-#[derive(Serialize, Deserialize)]
215
-pub struct Keypair {
216
-    public_key: Ed25519PublicKey,
217
-    secret_key: Ed25519SecretKey,
218
-}
219
-
220
-impl Keypair {
221
-    pub fn new(secret_key: Ed25519SecretKey) -> Self {
222
-        let public_key = Ed25519PublicKey::from(&secret_key);
223
-        Self {
224
-            public_key,
225
-            secret_key,
226
-        }
227
-    }
228
-
229
-    pub fn from_expanded_secret(expanded: &str) -> Result<Self> {
230
-        let secret_key = Ed25519SecretKey::from_expanded(expanded)?;
231
-        let public_key = Ed25519PublicKey::from(&secret_key);
232
-        Ok(Self {
233
-            public_key,
234
-            secret_key,
235
-        })
236
-    }
237
-
238
-    pub fn sign(&self, data: &[u8]) -> Ed25519Signature {
239
-        self.secret_key.sign(data, &self.public_key)
240
-    }
241
-
242
-    pub fn verify(&self, data: &[u8], signature: &Ed25519Signature) -> Result<()> {
243
-        self.public_key.verify(data, signature)
244
-    }
245
-
246
-    pub fn public_key(&self) -> &Ed25519PublicKey {
247
-        &self.public_key
248
-    }
249
-
250
-    pub fn secret_key(&self) -> &Ed25519SecretKey {
251
-        &self.secret_key
252
-    }
253
-}
254
-
255
-impl ToString for Keypair {
256
-    fn to_string(&self) -> String {
257
-        let keypair_bytes = self
258
-            .secret_key()
259
-            .as_bytes()
260
-            .iter()
261
-            .chain(self.public_key().as_bytes().iter())
262
-            .copied()
263
-            .collect_vec();
264
-
265
-        format!("{ED25519}:{}", bs58::encode(keypair_bytes).into_string())
266
-    }
267
-}
268
-
269
-impl FromStr for Keypair {
270
-    type Err = Error;
271
-
272
-    fn from_str(s: &str) -> Result<Self> {
273
-        let (key_type, data) = split_encoded_str(s)?;
274
-
275
-        if key_type != ED25519 {
276
-            return Err(Error::WrongKeyType {
277
-                key_type: key_type.to_owned(),
278
-                expected_key_type: ED25519,
279
-            });
280
-        }
281
-
282
-        let byte_data = bs58::decode(data)
283
-            .into_vec()
284
-            .map_err(|err| Error::from_string::<Keypair>(data.to_owned(), err.to_string()))?;
285
-
286
-        if byte_data.len() != ED25519_KEYPAIR_LENGTH {
287
-            return Err(Error::from_bytes::<Keypair>(
288
-                &byte_data,
289
-                format!(
290
-                    "Keypair byte array length doesn't equal\
291
-                     to requested length {ED25519_KEYPAIR_LENGTH}"
292
-                ),
293
-            ));
294
-        }
295
-
296
-        Ok(Self {
297
-            secret_key: Ed25519SecretKey::try_from_bytes(&byte_data[..ED25519_SECRET_KEY_LENGTH])?,
298
-            public_key: Ed25519PublicKey::try_from_bytes(&byte_data[ED25519_SECRET_KEY_LENGTH..])?,
299
-        })
300
-    }
301
-}
302
-
303
-serde_impl!(Ed25519PublicKey);
304
-serde_impl!(Ed25519SecretKey);
305
-serde_impl!(Ed25519Signature);

+ 0
- 165
common-api/src/crypto/key_exchange.rs View File

@@ -1,165 +0,0 @@
1
-//! ### Diffie–Hellman key exchange with ed25519 elliptic curves algorithm
2
-//! ---
3
-//! Used Dalek cryptography, and implemented [`Borsh`](https://borsh.io/) serialization for it
4
-
5
-use super::{
6
-    ed25519::{Ed25519PublicKey, Ed25519SecretKey},
7
-    Error, Key, Result, X25519,
8
-};
9
-use std::{
10
-    fmt::Display,
11
-    io::{Error as IoError, ErrorKind},
12
-};
13
-
14
-use borsh::{BorshDeserialize, BorshSerialize};
15
-use curve25519_dalek::edwards::CompressedEdwardsY;
16
-use x25519_dalek::{PublicKey as DalekPublicKey, StaticSecret};
17
-
18
-pub const PUBLIC_KEY_LENGTH: usize = 32_usize;
19
-pub const SECRET_KEY_LENGTH: usize = 32_usize;
20
-
21
-pub struct SecretKey(StaticSecret);
22
-
23
-impl BorshSerialize for SecretKey {
24
-    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
25
-        writer.write_all(&self.0.to_bytes())
26
-    }
27
-}
28
-
29
-impl BorshDeserialize for SecretKey {
30
-    fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
31
-        let secret_key = Self::try_from_bytes(std::mem::take(buf))
32
-            .map_err(|err| IoError::new(ErrorKind::InvalidData, err))?;
33
-        Ok(secret_key)
34
-    }
35
-}
36
-
37
-#[derive(Copy, Clone, PartialEq, Eq)]
38
-pub struct PublicKey(DalekPublicKey);
39
-
40
-impl BorshSerialize for PublicKey {
41
-    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
42
-        writer.write_all(self.0.as_bytes())
43
-    }
44
-}
45
-
46
-impl BorshDeserialize for PublicKey {
47
-    fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
48
-        let public_key = Self::try_from_bytes(std::mem::take(buf))
49
-            .map_err(|err| IoError::new(ErrorKind::InvalidData, err))?;
50
-        Ok(public_key)
51
-    }
52
-}
53
-
54
-impl Display for PublicKey {
55
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56
-        write!(f, "{}", self.string())
57
-    }
58
-}
59
-
60
-impl Key<SECRET_KEY_LENGTH> for SecretKey {
61
-    const KEY_TYPE: &'static str = X25519;
62
-
63
-    #[inline]
64
-    fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
65
-        self.0.to_bytes()
66
-    }
67
-
68
-    fn try_from_bytes(buf: &[u8]) -> Result<Self> {
69
-        if buf.len() != SECRET_KEY_LENGTH {
70
-            return Err(Error::from_bytes::<PublicKey>(
71
-                buf,
72
-                format!(
73
-                    "input buffer size \"{}\" not equal to secret key size \"{SECRET_KEY_LENGTH}\"",
74
-                    buf.len()
75
-                ),
76
-            ));
77
-        }
78
-
79
-        let mut temp_buf = [0_u8; SECRET_KEY_LENGTH];
80
-        temp_buf.copy_from_slice(buf);
81
-
82
-        Ok(Self(StaticSecret::from(temp_buf)))
83
-    }
84
-}
85
-
86
-impl Key<PUBLIC_KEY_LENGTH> for PublicKey {
87
-    const KEY_TYPE: &'static str = X25519;
88
-
89
-    #[inline]
90
-    fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] {
91
-        self.0.to_bytes()
92
-    }
93
-
94
-    fn try_from_bytes(buf: &[u8]) -> Result<Self> {
95
-        if buf.len() != PUBLIC_KEY_LENGTH {
96
-            return Err(Error::from_bytes::<PublicKey>(
97
-                buf,
98
-                format!(
99
-                    "input buffer size \"{}\" not equal to public key size \"{PUBLIC_KEY_LENGTH}\"",
100
-                    buf.len()
101
-                ),
102
-            ));
103
-        }
104
-
105
-        let mut temp_buf = [0_u8; PUBLIC_KEY_LENGTH];
106
-        temp_buf.copy_from_slice(buf);
107
-
108
-        Ok(Self(DalekPublicKey::from(temp_buf)))
109
-    }
110
-}
111
-
112
-impl<'a> From<&'a SecretKey> for PublicKey {
113
-    fn from(secret: &'a SecretKey) -> PublicKey {
114
-        Self(DalekPublicKey::from(&secret.0))
115
-    }
116
-}
117
-
118
-impl SecretKey {
119
-    /// Creates a secret part from other participant public part of keypair
120
-    ///
121
-    /// ## Arguments
122
-    /// - **other_public** - Another public part [`PublicKey`] of the key exchange process
123
-    ///
124
-    /// ## Returns
125
-    /// Byte array with a shared secret key
126
-    ///
127
-    pub fn exchange(&self, other_public: &PublicKey) -> [u8; SECRET_KEY_LENGTH] {
128
-        self.0.diffie_hellman(&other_public.0).to_bytes()
129
-    }
130
-}
131
-
132
-impl TryFrom<Ed25519PublicKey> for PublicKey {
133
-    type Error = Error;
134
-
135
-    fn try_from(key: Ed25519PublicKey) -> Result<Self> {
136
-        let edwards_point = CompressedEdwardsY::from_slice(key.as_bytes())
137
-            .decompress()
138
-            .ok_or_else(|| {
139
-                Error::from_bytes::<Ed25519PublicKey>(
140
-                    key.as_bytes(),
141
-                    "Couldn't decompress an Edwards point".to_owned(),
142
-                )
143
-            })?;
144
-
145
-        PublicKey::try_from_bytes(edwards_point.to_montgomery().as_bytes())
146
-    }
147
-}
148
-
149
-impl TryFrom<Ed25519SecretKey> for SecretKey {
150
-    type Error = Error;
151
-
152
-    fn try_from(key: Ed25519SecretKey) -> Result<Self> {
153
-        use ed25519_dalek::{ExpandedSecretKey, SecretKey as S};
154
-
155
-        let expanded_key =
156
-            ExpandedSecretKey::from(&S::from_bytes(key.as_bytes()).map_err(|err| {
157
-                Error::from_bytes::<Ed25519SecretKey>(key.as_bytes(), err.to_string())
158
-            })?);
159
-
160
-        Self::try_from_bytes(&expanded_key.to_bytes()[..32])
161
-    }
162
-}
163
-
164
-serde_impl!(SecretKey);
165
-serde_impl!(PublicKey);

+ 0
- 183
common-api/src/crypto/mod.rs View File

@@ -1,183 +0,0 @@
1
-#[macro_use]
2
-mod serde_impl {
3
-    macro_rules! serde_impl {
4
-        ($key_type: ty) => {
5
-            impl serde::Serialize for $key_type {
6
-                fn serialize<S>(
7
-                    &self,
8
-                    serializer: S,
9
-                ) -> std::result::Result<
10
-                    <S as serde::Serializer>::Ok,
11
-                    <S as serde::Serializer>::Error,
12
-                >
13
-                where
14
-                    S: serde::Serializer,
15
-                {
16
-                    serializer.serialize_str(&Key::string(self))
17
-                }
18
-            }
19
-
20
-            impl<'de> serde::Deserialize<'de> for $key_type {
21
-                fn deserialize<D>(
22
-                    deserializer: D,
23
-                ) -> std::result::Result<Self, <D as serde::Deserializer<'de>>::Error>
24
-                where
25
-                    D: serde::Deserializer<'de>,
26
-                {
27
-                    let s = <String as serde::Deserialize>::deserialize(deserializer)?;
28
-                    <$key_type>::from_string(&s).map_err(|err| {
29
-                        serde::de::Error::custom(format!("Deserialization failed: `{}`", err))
30
-                    })
31
-                }
32
-            }
33
-        };
34
-    }
35
-}
36
-
37
-pub mod ed25519;
38
-pub mod key_exchange;
39
-pub mod prelude {
40
-    pub use super::{
41
-        ed25519::{
42
-            Ed25519PublicKey, Ed25519SecretKey, Ed25519Signature, Keypair,
43
-            ED25519_PUBLIC_KEY_LENGTH, ED25519_SECRET_KEY_LENGTH, ED25519_SIGNATURE_LENGTH,
44
-        },
45
-        key_exchange::{PublicKey, SecretKey, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH},
46
-        Error, Key,
47
-    };
48
-}
49
-
50
-use itertools::Itertools;
51
-
52
-type Result<T> = std::result::Result<T, Error>;
53
-
54
-pub(crate) const ED25519: &str = "ed25519";
55
-pub(crate) const X25519: &str = "x25519";
56
-
57
-/// ## Key
58
-/// **KEY_LENGTH** - It's a key size for ed25519 or x25519
59
-/// **KEY_TYPE** - Key type, for internal usage to reduce a boilerplate code.
60
-/// It's a prefix for a key string serialization. Possible values are ["ed25519", "x25519"]
61
-pub trait Key<const KEY_LENGTH: usize>: Sized {
62
-    const KEY_TYPE: &'static str;
63
-
64
-    /// Parse an encoded string to the corresponding [`Key`]
65
-    fn from_string(key: &str) -> Result<Self> {
66
-        let (key_type, bs58_encoded) = split_encoded_str(key)?;
67
-
68
-        if key_type != Self::KEY_TYPE {
69
-            return Err(Error::WrongKeyType {
70
-                key_type: key_type.to_owned(),
71
-                expected_key_type: Self::KEY_TYPE,
72
-            });
73
-        }
74
-
75
-        let bytes = bs58::decode(bs58_encoded)
76
-            .into_vec()
77
-            .map_err(|err| Error::from_string::<Self>(bs58_encoded.to_owned(), err.to_string()))?;
78
-        Self::try_from_bytes(&bytes)
79
-    }
80
-
81
-    /// Return a string representation of a [`Key`]
82
-    /// The string is split with a delimiter ":"
83
-    /// The first part is a [`X25519`] or [`ED25519`] prefix
84
-    /// The second part is a bs58 encoded key
85
-    fn string(&self) -> String {
86
-        format!(
87
-            "{}:{}",
88
-            Self::KEY_TYPE,
89
-            bs58::encode(self.to_bytes()).into_string()
90
-        )
91
-    }
92
-
93
-    /// Parse a bytes slice to the corresponding [`Key`]
94
-    fn try_from_bytes(buf: &[u8]) -> Result<Self>;
95
-
96
-    /// Return a byte representation of a [`Key`]
97
-    /// The size of a slice defined with a [`KEY_LENGTH`]
98
-    fn to_bytes(&self) -> [u8; KEY_LENGTH];
99
-}
100
-
101
-#[derive(thiserror::Error, Debug)]
102
-pub enum Error {
103
-    #[error("Couldn't convert key from bytes \"{data}\" into \"{key_name}\", because of: {cause}")]
104
-    ConvertFromBytes {
105
-        key_name: &'static str,
106
-        data: String,
107
-        cause: String,
108
-    },
109
-    #[error(
110
-        "Couldn't convert key from string \"{data}\" into \"{key_name}\", because of: {cause}"
111
-    )]
112
-    ConvertFromString {
113
-        key_name: &'static str,
114
-        data: String,
115
-        cause: String,
116
-    },
117
-    #[error("The key format \"{0}\" seems different from ed25519 or x25519 format")]
118
-    UnknownKeyType(String),
119
-    #[error(
120
-        "The expected key type \"{expected_key_type}\" is different from actual \"{key_type}\""
121
-    )]
122
-    WrongKeyType {
123
-        key_type: String,
124
-        expected_key_type: &'static str,
125
-    },
126
-    #[error("Signature \"{0}\" verification failed")]
127
-    Verification(String),
128
-}
129
-
130
-impl Error {
131
-    pub(crate) fn from_string<T>(data: String, cause: String) -> Self {
132
-        Self::ConvertFromString {
133
-            key_name: std::any::type_name::<T>()
134
-                .rsplit("::")
135
-                .next()
136
-                .unwrap_or_default(),
137
-            data,
138
-            cause,
139
-        }
140
-    }
141
-
142
-    pub(crate) fn from_bytes<T>(data: &[u8], cause: String) -> Self {
143
-        Self::ConvertFromBytes {
144
-            key_name: std::any::type_name::<T>()
145
-                .rsplit("::")
146
-                .next()
147
-                .unwrap_or_default(),
148
-            data: bs58::encode(data).into_string(),
149
-            cause,
150
-        }
151
-    }
152
-}
153
-
154
-/// Split encoded [`str`] to key prefix and bs58 encoded string
155
-fn split_encoded_str(encoded: &str) -> Result<(&str, &str)> {
156
-    match encoded.split(':').next_tuple() {
157
-        Some((key_type @ ED25519, bs58_encoded) | (key_type @ X25519, bs58_encoded)) => {
158
-            Ok((key_type, bs58_encoded))
159
-        }
160
-        _ => Err(Error::UnknownKeyType(encoded.to_owned())),
161
-    }
162
-}
163
-
164
-#[cfg(test)]
165
-mod tests {
166
-
167
-    use super::{split_encoded_str, Error, ED25519, X25519};
168
-
169
-    #[test]
170
-    fn split_encoded() {
171
-        let bs58_str = bs58::encode(vec![0, 0, 0]).into_string();
172
-        assert!(matches!(
173
-                split_encoded_str(&format!("ed25519:{bs58_str}")),
174
-                Ok((key_type, s)) if key_type == ED25519 && s == bs58_str));
175
-        assert!(matches!(
176
-                split_encoded_str(&format!("x25519:{bs58_str}")),
177
-                Ok((key_type, s)) if key_type == X25519 && s == bs58_str));
178
-        assert!(matches!(
179
-            split_encoded_str(&bs58_str),
180
-            Err(Error::UnknownKeyType(..))
181
-        ));
182
-    }
183
-}

+ 1
- 1
common-api/src/headers.rs View File

@@ -1,5 +1,5 @@
1
-use crate::crypto::prelude::*;
2 1
 use near_account_id::AccountId;
2
+use near_client::crypto::prelude::*;
3 3
 use serde::{Deserialize, Serialize};
4 4
 
5 5
 pub const SIGNATURE_HEADER_NAME: &str = "signature";

+ 0
- 3
common-api/src/lib.rs View File

@@ -1,5 +1,2 @@
1
-#[cfg(feature = "api")]
2 1
 pub mod api;
3
-pub mod crypto;
4
-#[cfg(feature = "headers")]
5 2
 pub mod headers;

+ 0
- 325
common-api/tests/crypto.rs View File

@@ -1,325 +0,0 @@
1
-use std::str::FromStr;
2
-
3
-use borsh::BorshDeserialize;
4
-use common_api::crypto::prelude::*;
5
-use ed25519_dalek::{ExpandedSecretKey, SecretKey as DalekSecretKey};
6
-use rand::{RngCore, SeedableRng};
7
-use rand_chacha::ChaChaRng;
8
-
9
-#[test]
10
-fn try_from_bytes_ed25519() {
11
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
12
-    let pk = Ed25519PublicKey::from(&sk);
13
-    let _ = Ed25519PublicKey::try_from_bytes(pk.as_bytes()).unwrap();
14
-
15
-    assert!(matches!(
16
-        Ed25519PublicKey::try_from_bytes(&[0, 0, 0]),
17
-        Err(Error::ConvertFromBytes { .. })
18
-    ));
19
-
20
-    assert!(matches!(
21
-        Ed25519SecretKey::try_from_bytes(&[0, 0, 0]),
22
-        Err(Error::ConvertFromBytes { .. })
23
-    ));
24
-}
25
-
26
-#[test]
27
-fn to_string_ed25519() {
28
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
29
-    let pk = Ed25519PublicKey::from(&sk);
30
-
31
-    assert_eq!(
32
-        format!("ed25519:{}", bs58::encode(sk.as_bytes()).into_string()),
33
-        sk.string()
34
-    );
35
-    assert_eq!(
36
-        format!("ed25519:{}", bs58::encode(pk.as_bytes()).into_string()),
37
-        pk.string()
38
-    );
39
-}
40
-
41
-#[test]
42
-fn from_string_ed25519() {
43
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
44
-    let pk = Ed25519PublicKey::from(&sk);
45
-
46
-    let _ = Ed25519SecretKey::from_string(
47
-        format!("ed25519:{}", bs58::encode(sk.as_bytes()).into_string()).as_str(),
48
-    )
49
-    .unwrap();
50
-
51
-    let _ = Ed25519PublicKey::from_string(
52
-        format!("ed25519:{}", bs58::encode(pk.as_bytes()).into_string()).as_str(),
53
-    )
54
-    .unwrap();
55
-
56
-    assert!(matches!(
57
-        Ed25519PublicKey::from_string(
58
-            format!("x25519:{}", bs58::encode(vec![0, 0, 0]).into_string()).as_str()
59
-        ),
60
-        Err(Error::WrongKeyType { .. })
61
-    ));
62
-
63
-    assert!(matches!(
64
-        Ed25519SecretKey::from_string(
65
-            format!("x25519:{}", bs58::encode(vec![0, 0, 0]).into_string()).as_str(),
66
-        ),
67
-        Err(Error::WrongKeyType { .. })
68
-    ));
69
-
70
-    assert!(matches!(
71
-        Ed25519SecretKey::from_string(format!("ed25519:{}", "==1234%#").as_str(),),
72
-        Err(Error::ConvertFromString { .. })
73
-    ));
74
-
75
-    assert!(matches!(
76
-        Ed25519PublicKey::from_string(
77
-            format!("ed25519:{}", bs58::encode(vec![0, 0, 0]).into_string()).as_str(),
78
-        ),
79
-        Err(Error::ConvertFromBytes { .. })
80
-    ));
81
-
82
-    assert!(matches!(
83
-        Ed25519PublicKey::from_string(format!("ed25519:{}", "==1234%#").as_str(),),
84
-        Err(Error::ConvertFromString { .. })
85
-    ));
86
-}
87
-
88
-#[test]
89
-fn from_expanded() {
90
-    let dalek_sk = ExpandedSecretKey::from(&DalekSecretKey::from_bytes(&random_bits()).unwrap());
91
-    let exp_str = format!(
92
-        "ed25519:{}",
93
-        bs58::encode(dalek_sk.to_bytes()).into_string()
94
-    );
95
-    let sk = Ed25519SecretKey::from_expanded(&exp_str).unwrap();
96
-
97
-    assert_eq!(sk.as_bytes(), &dalek_sk.to_bytes()[..32]);
98
-}
99
-
100
-#[test]
101
-fn from_expanded_fail() {
102
-    let dalek_sk = ExpandedSecretKey::from(&DalekSecretKey::from_bytes(&random_bits()).unwrap());
103
-
104
-    let exp_str = bs58::encode(dalek_sk.to_bytes()).into_string();
105
-    assert!(matches!(
106
-        Ed25519SecretKey::from_expanded(&exp_str),
107
-        Err(Error::UnknownKeyType { .. })
108
-    ));
109
-
110
-    let exp_str = format!("ed25519:{}", bs58::encode(vec![0, 0, 0]).into_string());
111
-    assert!(matches!(
112
-        Ed25519SecretKey::from_expanded(&exp_str),
113
-        Err(Error::ConvertFromBytes { .. })
114
-    ));
115
-
116
-    let exp_str = format!("ed25519:{}", "===%123@@#31");
117
-    assert!(matches!(
118
-        Ed25519SecretKey::from_expanded(&exp_str),
119
-        Err(Error::ConvertFromString { .. })
120
-    ));
121
-}
122
-
123
-#[test]
124
-fn try_from_bytes_x25519() {
125
-    let sk = SecretKey::try_from_bytes(&random_bits()).unwrap();
126
-    let pk = PublicKey::from(&sk);
127
-    let _ = PublicKey::try_from_bytes(&pk.to_bytes()).unwrap();
128
-
129
-    assert!(matches!(
130
-        PublicKey::try_from_bytes(&[0, 0, 0]),
131
-        Err(Error::ConvertFromBytes { .. })
132
-    ));
133
-
134
-    assert!(matches!(
135
-        SecretKey::try_from_bytes(&[0, 0, 0]),
136
-        Err(Error::ConvertFromBytes { .. })
137
-    ));
138
-}
139
-
140
-#[test]
141
-fn to_string_x25519() {
142
-    let sk = SecretKey::try_from_bytes(&random_bits()).unwrap();
143
-    let pk = PublicKey::from(&sk);
144
-
145
-    assert_eq!(
146
-        format!("x25519:{}", bs58::encode(&sk.to_bytes()).into_string()),
147
-        sk.string()
148
-    );
149
-    assert_eq!(
150
-        format!("x25519:{}", bs58::encode(&pk.to_bytes()).into_string()),
151
-        pk.string()
152
-    );
153
-}
154
-
155
-#[test]
156
-fn from_string_x25519() {
157
-    let sk = SecretKey::try_from_bytes(&random_bits()).unwrap();
158
-    let pk = PublicKey::from(&sk);
159
-
160
-    let _ = SecretKey::from_string(
161
-        format!("x25519:{}", bs58::encode(&sk.to_bytes()).into_string()).as_str(),
162
-    )
163
-    .unwrap();
164
-
165
-    let _ = PublicKey::from_string(
166
-        format!("x25519:{}", bs58::encode(&pk.to_bytes()).into_string()).as_str(),
167
-    )
168
-    .unwrap();
169
-
170
-    assert!(matches!(
171
-        PublicKey::from_string(
172
-            format!("ed25519:{}", bs58::encode(vec![0, 0, 0]).into_string()).as_str()
173
-        ),
174
-        Err(Error::WrongKeyType { .. })
175
-    ));
176
-
177
-    assert!(matches!(
178
-        SecretKey::from_string(
179
-            format!("ed25519:{}", bs58::encode(vec![0, 0, 0]).into_string()).as_str(),
180
-        ),
181
-        Err(Error::WrongKeyType { .. })
182
-    ));
183
-
184
-    assert!(matches!(
185
-        SecretKey::from_string(
186
-            format!("x25519:{}", bs58::encode(vec![0, 0, 0]).into_string()).as_str(),
187
-        ),
188
-        Err(Error::ConvertFromBytes { .. })
189
-    ));
190
-
191
-    assert!(matches!(
192
-        SecretKey::from_string(format!("x25519:{}", "==1234%#").as_str(),),
193
-        Err(Error::ConvertFromString { .. })
194
-    ));
195
-
196
-    assert!(matches!(
197
-        PublicKey::from_string(
198
-            format!("x25519:{}", bs58::encode(vec![0, 0, 0]).into_string()).as_str(),
199
-        ),
200
-        Err(Error::ConvertFromBytes { .. })
201
-    ));
202
-
203
-    assert!(matches!(
204
-        PublicKey::from_string(format!("x25519:{}", "==1234%#").as_str(),),
205
-        Err(Error::ConvertFromString { .. })
206
-    ));
207
-}
208
-
209
-#[test]
210
-fn public_key_verify() {
211
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
212
-    let pk = Ed25519PublicKey::from(&sk);
213
-
214
-    let signature = sk.sign(b"message", &pk);
215
-    pk.verify(b"message", &signature).unwrap();
216
-}
217
-
218
-#[test]
219
-fn keypair_verify() {
220
-    let keypair = Keypair::new(Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap());
221
-    let signature = keypair.sign(b"message");
222
-    keypair.verify(b"message", &signature).unwrap();
223
-}
224
-
225
-#[test]
226
-fn key_exchange() {
227
-    let alice_sk = SecretKey::try_from_bytes(&random_bits()).unwrap();
228
-    let alice_pk = PublicKey::from(&alice_sk);
229
-
230
-    let bob_sk = SecretKey::try_from_bytes(&random_bits()).unwrap();
231
-    let bob_pk = PublicKey::from(&bob_sk);
232
-
233
-    assert_eq!(alice_sk.exchange(&bob_pk), bob_sk.exchange(&alice_pk));
234
-}
235
-
236
-#[test]
237
-fn borsh_ed25519() {
238
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
239
-    let sk_bytes = borsh::to_vec(&sk).unwrap();
240
-    let pk = Ed25519PublicKey::from(&sk);
241
-    let pk_bytes = borsh::to_vec(&pk).unwrap();
242
-
243
-    assert_eq!(pk_bytes.len(), pk.as_bytes().len() + 1);
244
-    assert_eq!(pk_bytes[0], 0);
245
-    assert_eq!(sk_bytes.len(), sk.as_bytes().len());
246
-
247
-    let sk = Ed25519SecretKey::try_from_slice(&sk_bytes).unwrap();
248
-    let pk = Ed25519PublicKey::try_from_slice(&pk_bytes).unwrap();
249
-
250
-    let signature_bytes = borsh::to_vec(&sk.sign(b"message", &pk)).unwrap();
251
-    pk.verify(
252
-        b"message",
253
-        &Ed25519Signature::try_from_slice(&signature_bytes).unwrap(),
254
-    )
255
-    .unwrap();
256
-}
257
-
258
-#[test]
259
-fn borsh_x25519() {
260
-    let sk = SecretKey::try_from_bytes(&random_bits()).unwrap();
261
-    let sk_bytes = borsh::to_vec(&sk).unwrap();
262
-    let pk = PublicKey::from(&sk);
263
-    let pk_bytes = borsh::to_vec(&pk).unwrap();
264
-
265
-    // just try to serialize and deserialize. We doesn't support key-exchange for now
266
-    let _ = SecretKey::try_from_slice(&sk_bytes).unwrap();
267
-    let _ = PublicKey::try_from_slice(&pk_bytes).unwrap();
268
-}
269
-
270
-#[test]
271
-fn keypair_from_str() {
272
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
273
-    let pk = Ed25519PublicKey::from(&sk);
274
-
275
-    let mut sk_bytes = sk.to_bytes().to_vec();
276
-    sk_bytes.extend_from_slice(&pk.to_bytes());
277
-
278
-    let keypair_bs58 = format!("ed25519:{}", bs58::encode(sk_bytes).into_string());
279
-
280
-    let keypair = Keypair::from_str(&keypair_bs58).unwrap();
281
-
282
-    assert_eq!(keypair.secret_key().to_bytes(), sk.to_bytes());
283
-    assert_eq!(keypair.public_key().to_bytes(), pk.to_bytes());
284
-}
285
-
286
-#[test]
287
-fn keypair_to_string() {
288
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
289
-    let pk = Ed25519PublicKey::from(&sk);
290
-
291
-    let mut sk_bytes = sk.to_bytes().to_vec();
292
-    sk_bytes.extend_from_slice(&pk.to_bytes());
293
-
294
-    let keypair_bs58 = format!("ed25519:{}", bs58::encode(sk_bytes).into_string());
295
-    let keypair = Keypair::new(sk);
296
-
297
-    assert_eq!(keypair_bs58, keypair.to_string());
298
-}
299
-
300
-#[test]
301
-fn convert_from_edwards_to_montgomery() {
302
-    let alice_sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
303
-    let bob_sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
304
-
305
-    let alice_pk = Ed25519PublicKey::from(&alice_sk);
306
-    let bob_pk = Ed25519PublicKey::from(&bob_sk);
307
-
308
-    let alice_sk_dhx = SecretKey::try_from(alice_sk).unwrap();
309
-    let bob_sk_dhx = SecretKey::try_from(bob_sk).unwrap();
310
-
311
-    let alice_pk_dhx = PublicKey::try_from(alice_pk).unwrap();
312
-    let bob_pk_dhx = PublicKey::try_from(bob_pk).unwrap();
313
-
314
-    assert_eq!(
315
-        alice_sk_dhx.exchange(&bob_pk_dhx),
316
-        bob_sk_dhx.exchange(&alice_pk_dhx)
317
-    );
318
-}
319
-
320
-fn random_bits() -> [u8; ED25519_SECRET_KEY_LENGTH] {
321
-    let mut chacha = ChaChaRng::from_entropy();
322
-    let mut secret_bytes = [0_u8; ED25519_SECRET_KEY_LENGTH];
323
-    chacha.fill_bytes(&mut secret_bytes);
324
-    secret_bytes
325
-}

+ 0
- 17
near-primitives-light/Cargo.toml View File

@@ -1,17 +0,0 @@
1
-[package]
2
-name = "near-primitives-light"
3
-version = "0.1.0"
4
-edition = "2021"
5
-authors = ["silvestr@relayz.io"]
6
-description = """
7
-Copy-paste from a https://github.com/near/nearcore.
8
-It's a reduced implementation of near primitives.
9
-"""
10
-
11
-[dependencies]
12
-borsh = "0.9"
13
-common-api = { path = "../common-api" }
14
-chrono = { version = "0.4", features = ["serde"] }
15
-serde = { version = "1", default-features = false, features = ["derive", "rc"] }
16
-near-primitives-core = "0.15"
17
-near-vm-errors = "3.1"

+ 0
- 802
near-primitives-light/src/errors.rs View File

@@ -1,802 +0,0 @@
1
-use serde::{Deserialize, Serialize};
2
-use std::fmt::{Debug, Display};
3
-
4
-use near_primitives_core::{
5
-    hash::CryptoHash,
6
-    serialize::dec_format,
7
-    types::{AccountId, Balance, Gas, Nonce},
8
-};
9
-
10
-use common_api::crypto::prelude::*;
11
-
12
-use borsh::{BorshDeserialize, BorshSerialize};
13
-
14
-/// Error returned in the ExecutionOutcome in case of failure
15
-#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
16
-pub enum TxExecutionError {
17
-    /// An error happened during Action execution
18
-    ActionError(ActionError),
19
-    /// An error happened during Transaction execution
20
-    InvalidTxError(InvalidTxError),
21
-}
22
-
23
-impl std::error::Error for TxExecutionError {}
24
-
25
-impl Display for TxExecutionError {
26
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
27
-        match self {
28
-            TxExecutionError::ActionError(e) => write!(f, "{e}"),
29
-            TxExecutionError::InvalidTxError(e) => write!(f, "{e}"),
30
-        }
31
-    }
32
-}
33
-
34
-impl From<ActionError> for TxExecutionError {
35
-    fn from(error: ActionError) -> Self {
36
-        TxExecutionError::ActionError(error)
37
-    }
38
-}
39
-
40
-impl From<InvalidTxError> for TxExecutionError {
41
-    fn from(error: InvalidTxError) -> Self {
42
-        TxExecutionError::InvalidTxError(error)
43
-    }
44
-}
45
-
46
-/// Error returned from `Runtime::apply`
47
-#[derive(Debug, Clone, PartialEq, Eq)]
48
-pub enum RuntimeError {
49
-    /// An unexpected integer overflow occurred. The likely issue is an invalid state or the transition.
50
-    UnexpectedIntegerOverflow,
51
-    /// An error happened during TX verification and account charging. It's likely the chunk is invalid.
52
-    /// and should be challenged.
53
-    InvalidTxError(InvalidTxError),
54
-    /// Unexpected error which is typically related to the node storage corruption.
55
-    /// It's possible the input state is invalid or malicious.
56
-    StorageError(StorageError),
57
-    /// An error happens if `check_balance` fails, which is likely an indication of an invalid state.
58
-    BalanceMismatchError(BalanceMismatchError),
59
-    /// The incoming receipt didn't pass the validation, it's likely a malicious behaviour.
60
-    ReceiptValidationError(ReceiptValidationError),
61
-    /// Error when accessing validator information. Happens inside epoch manager.
62
-    ValidatorError(EpochError),
63
-}
64
-
65
-impl std::fmt::Display for RuntimeError {
66
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
67
-        f.write_str(&format!("{self:?}"))
68
-    }
69
-}
70
-
71
-impl std::error::Error for RuntimeError {}
72
-
73
-/// Internal
74
-#[derive(Debug, Clone, PartialEq, Eq)]
75
-pub enum StorageError {
76
-    /// Key-value db internal failure
77
-    StorageInternalError,
78
-    /// Storage is PartialStorage and requested a missing trie node
79
-    TrieNodeMissing,
80
-    /// Either invalid state or key-value db is corrupted.
81
-    /// For PartialStorage it cannot be corrupted.
82
-    /// Error message is unreliable and for debugging purposes only. It's also probably ok to
83
-    /// panic in every place that produces this error.
84
-    /// We can check if db is corrupted by verifying everything in the state trie.
85
-    StorageInconsistentState(String),
86
-    /// Error from flat storage
87
-    FlatStorageError(String),
88
-}
89
-
90
-impl std::fmt::Display for StorageError {
91
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
92
-        f.write_str(&format!("{self:?}"))
93
-    }
94
-}
95
-
96
-impl std::error::Error for StorageError {}
97
-
98
-/// An error happened during TX execution
99
-#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
100
-pub enum InvalidTxError {
101
-    /// Happens if a wrong AccessKey used or AccessKey has not enough permissions
102
-    InvalidAccessKeyError(InvalidAccessKeyError),
103
-    /// TX signer_id is not a valid [`AccountId`]
104
-    InvalidSignerId { signer_id: String },
105
-    /// TX signer_id is not found in a storage
106
-    SignerDoesNotExist { signer_id: AccountId },
107
-    /// Transaction nonce must be `account[access_key].nonce + 1`.
108
-    InvalidNonce { tx_nonce: Nonce, ak_nonce: Nonce },
109
-    /// Transaction nonce is larger than the upper bound given by the block height
110
-    NonceTooLarge { tx_nonce: Nonce, upper_bound: Nonce },
111
-    /// TX receiver_id is not a valid AccountId
112
-    InvalidReceiverId { receiver_id: String },
113
-    /// TX signature is not valid
114
-    InvalidSignature,
115
-    /// Account does not have enough balance to cover TX cost
116
-    NotEnoughBalance {
117
-        signer_id: AccountId,
118
-        #[serde(with = "dec_format")]
119
-        balance: Balance,
120
-        #[serde(with = "dec_format")]
121
-        cost: Balance,
122
-    },
123
-    /// Signer account doesn't have enough balance after transaction.
124
-    LackBalanceForState {
125
-        /// An account which doesn't have enough balance to cover storage.
126
-        signer_id: AccountId,
127
-        /// Required balance to cover the state.
128
-        #[serde(with = "dec_format")]
129
-        amount: Balance,
130
-    },
131
-    /// An integer overflow occurred during transaction cost estimation.
132
-    CostOverflow,
133
-    /// Transaction parent block hash doesn't belong to the current chain
134
-    InvalidChain,
135
-    /// Transaction has expired
136
-    Expired,
137
-    /// An error occurred while validating actions of a Transaction.
138
-    ActionsValidation(ActionsValidationError),
139
-    /// The size of serialized transaction exceeded the limit.
140
-    TransactionSizeExceeded { size: u64, limit: u64 },
141
-}
142
-
143
-impl std::error::Error for InvalidTxError {}
144
-
145
-#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
146
-pub enum InvalidAccessKeyError {
147
-    /// The access key identified by the `public_key` doesn't exist for the account
148
-    AccessKeyNotFound {
149
-        account_id: AccountId,
150
-        public_key: Ed25519PublicKey,
151
-    },
152
-    /// Transaction `receiver_id` doesn't match the access key receiver_id
153
-    ReceiverMismatch {
154
-        tx_receiver: AccountId,
155
-        ak_receiver: String,
156
-    },
157
-    /// Transaction method name isn't allowed by the access key
158
-    MethodNameMismatch { method_name: String },
159
-    /// Transaction requires a full permission access key.
160
-    RequiresFullAccess,
161
-    /// Access Key does not have enough allowance to cover transaction cost
162
-    NotEnoughAllowance {
163
-        account_id: AccountId,
164
-        public_key: Ed25519PublicKey,
165
-        #[serde(with = "dec_format")]
166
-        allowance: Balance,
167
-        #[serde(with = "dec_format")]
168
-        cost: Balance,
169
-    },
170
-    /// Having a deposit with a function call action is not allowed with a function call access key.
171
-    DepositWithFunctionCall,
172
-}
173
-
174
-/// Describes the error for validating a list of actions.
175
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
176
-pub enum ActionsValidationError {
177
-    /// The delete action must be a final aciton in transaction
178
-    DeleteActionMustBeFinal,
179
-    /// The total prepaid gas (for all given actions) exceeded the limit.
180
-    TotalPrepaidGasExceeded { total_prepaid_gas: Gas, limit: Gas },
181
-    /// The number of actions exceeded the given limit.
182
-    TotalNumberOfActionsExceeded {
183
-        total_number_of_actions: u64,
184
-        limit: u64,
185
-    },
186
-    /// The total number of bytes of the method names exceeded the limit in a Add Key action.
187
-    AddKeyMethodNamesNumberOfBytesExceeded {
188
-        total_number_of_bytes: u64,
189
-        limit: u64,
190
-    },
191
-    /// The length of some method name exceeded the limit in a Add Key action.
192
-    AddKeyMethodNameLengthExceeded { length: u64, limit: u64 },
193
-    /// Integer overflow during a compute.
194
-    IntegerOverflow,
195
-    /// Invalid account ID.
196
-    InvalidAccountId { account_id: String },
197
-    /// The size of the contract code exceeded the limit in a DeployContract action.
198
-    ContractSizeExceeded { size: u64, limit: u64 },
199
-    /// The length of the method name exceeded the limit in a Function Call action.
200
-    FunctionCallMethodNameLengthExceeded { length: u64, limit: u64 },
201
-    /// The length of the arguments exceeded the limit in a Function Call action.
202
-    FunctionCallArgumentsLengthExceeded { length: u64, limit: u64 },
203
-    /// An attempt to stake with a public key that is not convertible to ristretto.
204
-    UnsuitableStakingKey { public_key: Ed25519PublicKey },
205
-    /// The attached amount of gas in a FunctionCall action has to be a positive number.
206
-    FunctionCallZeroAttachedGas,
207
-}
208
-
209
-/// Describes the error for validating a receipt.
210
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
211
-pub enum ReceiptValidationError {
212
-    /// The `predecessor_id` of a Receipt is not valid.
213
-    InvalidPredecessorId { account_id: String },
214
-    /// The `receiver_id` of a Receipt is not valid.
215
-    InvalidReceiverId { account_id: String },
216
-    /// The `signer_id` of an ActionReceipt is not valid.
217
-    InvalidSignerId { account_id: String },
218
-    /// The `receiver_id` of a DataReceiver within an ActionReceipt is not valid.
219
-    InvalidDataReceiverId { account_id: String },
220
-    /// The length of the returned data exceeded the limit in a DataReceipt.
221
-    ReturnedValueLengthExceeded { length: u64, limit: u64 },
222
-    /// The number of input data dependencies exceeds the limit in an ActionReceipt.
223
-    NumberInputDataDependenciesExceeded {
224
-        number_of_input_data_dependencies: u64,
225
-        limit: u64,
226
-    },
227
-    /// An error occurred while validating actions of an ActionReceipt.
228
-    ActionsValidation(ActionsValidationError),
229
-}
230
-
231
-impl Display for ReceiptValidationError {
232
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
233
-        match self {
234
-            ReceiptValidationError::InvalidPredecessorId { account_id } => {
235
-                write!(f, "The predecessor_id `{account_id}` of a Receipt is not valid.")
236
-            }
237
-            ReceiptValidationError::InvalidReceiverId { account_id } => {
238
-                write!(f, "The receiver_id `{account_id}` of a Receipt is not valid.")
239
-            }
240
-            ReceiptValidationError::InvalidSignerId { account_id } => {
241
-                write!(f, "The signer_id `{account_id}` of an ActionReceipt is not valid.")
242
-            }
243
-            ReceiptValidationError::InvalidDataReceiverId { account_id } => write!(
244
-                f,
245
-                "The receiver_id `{account_id}` of a DataReceiver within an ActionReceipt is not valid."
246
-            ),
247
-            ReceiptValidationError::ReturnedValueLengthExceeded { length, limit } => write!(
248
-                f,
249
-                "The length of the returned data {length} exceeded the limit {limit} in a DataReceipt"
250
-            ),
251
-            ReceiptValidationError::NumberInputDataDependenciesExceeded { number_of_input_data_dependencies, limit } => write!(
252
-                f,
253
-                "The number of input data dependencies {number_of_input_data_dependencies} exceeded the limit {limit} in an ActionReceipt"
254
-            ),
255
-            ReceiptValidationError::ActionsValidation(e) => write!(f, "{e}"),
256
-        }
257
-    }
258
-}
259
-
260
-impl std::error::Error for ReceiptValidationError {}
261
-
262
-impl Display for ActionsValidationError {
263
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
264
-        match self {
265
-            ActionsValidationError::DeleteActionMustBeFinal => {
266
-                write!(f, "The delete action must be the last action in transaction")
267
-            }
268
-            ActionsValidationError::TotalPrepaidGasExceeded { total_prepaid_gas, limit } => {
269
-                write!(f, "The total prepaid gas {total_prepaid_gas} exceeds the limit {limit}")
270
-            }
271
-            ActionsValidationError::TotalNumberOfActionsExceeded {total_number_of_actions, limit } => {
272
-                write!(
273
-                    f,
274
-                    "The total number of actions {total_number_of_actions} exceeds the limit {limit}"
275
-                )
276
-            }
277
-            ActionsValidationError::AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes, limit } => write!(
278
-                f,
279
-                "The total number of bytes in allowed method names {total_number_of_bytes} exceeds the maximum allowed number {limit} in a AddKey action"
280
-            ),
281
-            ActionsValidationError::AddKeyMethodNameLengthExceeded { length, limit } => write!(
282
-                f,
283
-                "The length of some method name {length} exceeds the maximum allowed length {limit} in a AddKey action"
284
-            ),
285
-            ActionsValidationError::IntegerOverflow => write!(
286
-                f,
287
-                "Integer overflow during a compute",
288
-            ),
289
-            ActionsValidationError::InvalidAccountId { account_id } => write!(
290
-                f,
291
-                "Invalid account ID `{account_id}`"
292
-            ),
293
-            ActionsValidationError::ContractSizeExceeded { size, limit } => write!(
294
-                f,
295
-                "The length of the contract size {size} exceeds the maximum allowed size {limit} in a DeployContract action"
296
-            ),
297
-            ActionsValidationError::FunctionCallMethodNameLengthExceeded { length, limit } => write!(
298
-                f,
299
-                "The length of the method name {length} exceeds the maximum allowed length {limit} in a FunctionCall action"
300
-            ),
301
-            ActionsValidationError::FunctionCallArgumentsLengthExceeded { length, limit } => write!(
302
-                f,
303
-                "The length of the arguments {length} exceeds the maximum allowed length {limit} in a FunctionCall action"
304
-            ),
305
-            ActionsValidationError::UnsuitableStakingKey { public_key } => write!(
306
-                f,
307
-                "The staking key must be ristretto compatible ED25519 key. {public_key} is provided instead."
308
-            ),
309
-            ActionsValidationError::FunctionCallZeroAttachedGas => write!(
310
-                f,
311
-                "The attached amount of gas in a FunctionCall action has to be a positive number",
312
-            ),
313
-        }
314
-    }
315
-}
316
-
317
-impl std::error::Error for ActionsValidationError {}
318
-
319
-/// An error happened during Action execution
320
-#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
321
-pub struct ActionError {
322
-    /// Index of the failed action in the transaction.
323
-    /// Action index is not defined if ActionError.kind is `ActionErrorKind::LackBalanceForState`
324
-    pub index: Option<u64>,
325
-    /// The kind of ActionError happened
326
-    pub kind: ActionErrorKind,
327
-}
328
-
329
-impl std::error::Error for ActionError {}
330
-
331
-#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
332
-pub enum ActionErrorKind {
333
-    /// Happens when CreateAccount action tries to create an account with account_id which is already exists in the storage
334
-    AccountAlreadyExists { account_id: AccountId },
335
-    /// Happens when TX receiver_id doesn't exist (but action is not Action::CreateAccount)
336
-    AccountDoesNotExist { account_id: AccountId },
337
-    /// A top-level account ID can only be created by registrar.
338
-    CreateAccountOnlyByRegistrar {
339
-        account_id: AccountId,
340
-        registrar_account_id: AccountId,
341
-        predecessor_id: AccountId,
342
-    },
343
-    /// A newly created account must be under a namespace of the creator account
344
-    CreateAccountNotAllowed {
345
-        account_id: AccountId,
346
-        predecessor_id: AccountId,
347
-    },
348
-    /// Administrative actions like `DeployContract`, `Stake`, `AddKey`, `DeleteKey`. can be proceed only if sender=receiver
349
-    /// or the first TX action is a `CreateAccount` action
350
-    ActorNoPermission {
351
-        account_id: AccountId,
352
-        actor_id: AccountId,
353
-    },
354
-    /// Account tries to remove an access key that doesn't exist
355
-    DeleteKeyDoesNotExist {
356
-        account_id: AccountId,
357
-        public_key: Ed25519PublicKey,
358
-    },
359
-    /// The public key is already used for an existing access key
360
-    AddKeyAlreadyExists {
361
-        account_id: AccountId,
362
-        public_key: Ed25519PublicKey,
363
-    },
364
-    /// Account is staking and can not be deleted
365
-    DeleteAccountStaking { account_id: AccountId },
366
-    /// ActionReceipt can't be completed, because the remaining balance will not be enough to cover storage.
367
-    LackBalanceForState {
368
-        /// An account which needs balance
369
-        account_id: AccountId,
370
-        /// Balance required to complete an action.
371
-        #[serde(with = "dec_format")]
372
-        amount: Balance,
373
-    },
374
-    /// Account is not yet staked, but tries to unstake
375
-    TriesToUnstake { account_id: AccountId },
376
-    /// The account doesn't have enough balance to increase the stake.
377
-    TriesToStake {
378
-        account_id: AccountId,
379
-        #[serde(with = "dec_format")]
380
-        stake: Balance,
381
-        #[serde(with = "dec_format")]
382
-        locked: Balance,
383
-        #[serde(with = "dec_format")]
384
-        balance: Balance,
385
-    },
386
-    InsufficientStake {
387
-        account_id: AccountId,
388
-        #[serde(with = "dec_format")]
389
-        stake: Balance,
390
-        #[serde(with = "dec_format")]
391
-        minimum_stake: Balance,
392
-    },
393
-    /// An error occurred during a `FunctionCall` Action, parameter is debug message.
394
-    FunctionCallError(near_vm_errors::FunctionCallErrorSer),
395
-    /// Error occurs when a new `ActionReceipt` created by the `FunctionCall` action fails
396
-    /// receipt validation.
397
-    NewReceiptValidationError(ReceiptValidationError),
398
-    /// Error occurs when a `CreateAccount` action is called on hex-characters
399
-    /// account of length 64.  See implicit account creation NEP:
400
-    /// <https://github.com/nearprotocol/NEPs/pull/71>.
401
-    OnlyImplicitAccountCreationAllowed { account_id: AccountId },
402
-    /// Delete account whose state is large is temporarily banned.
403
-    DeleteAccountWithLargeState { account_id: AccountId },
404
-}
405
-
406
-impl From<ActionErrorKind> for ActionError {
407
-    fn from(e: ActionErrorKind) -> ActionError {
408
-        ActionError {
409
-            index: None,
410
-            kind: e,
411
-        }
412
-    }
413
-}
414
-
415
-impl Display for InvalidTxError {
416
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
417
-        match self {
418
-            InvalidTxError::InvalidSignerId { signer_id } => {
419
-                write!(
420
-                    f,
421
-                    "Invalid signer account ID {signer_id:?} according to requirements"
422
-                )
423
-            }
424
-            InvalidTxError::SignerDoesNotExist { signer_id } => {
425
-                write!(f, "Signer {signer_id:?} does not exist")
426
-            }
427
-            InvalidTxError::InvalidAccessKeyError(access_key_error) => {
428
-                Display::fmt(&access_key_error, f)
429
-            }
430
-            InvalidTxError::InvalidNonce { tx_nonce, ak_nonce } => write!(
431
-                f,
432
-                "Transaction nonce {tx_nonce} must be larger than nonce of the used access key {ak_nonce}"
433
-            ),
434
-            InvalidTxError::InvalidReceiverId { receiver_id } => {
435
-                write!(
436
-                    f,
437
-                    "Invalid receiver account ID {receiver_id:?} according to requirements"
438
-                )
439
-            }
440
-            InvalidTxError::InvalidSignature => {
441
-                write!(f, "Transaction is not signed with the given public key")
442
-            }
443
-            InvalidTxError::NotEnoughBalance {
444
-                signer_id,
445
-                balance,
446
-                cost,
447
-            } => write!(
448
-                f,
449
-                "Sender {signer_id:?} does not have enough balance {balance} for operation costing {cost}"
450
-            ),
451
-            InvalidTxError::LackBalanceForState { signer_id, amount } => {
452
-                write!(f, "Failed to execute, because the account {signer_id:?} wouldn't have enough balance to cover storage, required to have {amount} yoctoNEAR more")
453
-            }
454
-            InvalidTxError::CostOverflow => {
455
-                write!(f, "Transaction gas or balance cost is too high")
456
-            }
457
-            InvalidTxError::InvalidChain => {
458
-                write!(
459
-                    f,
460
-                    "Transaction parent block hash doesn't belong to the current chain"
461
-                )
462
-            }
463
-            InvalidTxError::Expired => {
464
-                write!(f, "Transaction has expired")
465
-            }
466
-            InvalidTxError::ActionsValidation(error) => {
467
-                write!(f, "Transaction actions validation error: {error}")
468
-            }
469
-            InvalidTxError::NonceTooLarge {
470
-                tx_nonce,
471
-                upper_bound,
472
-            } => {
473
-                write!(
474
-                    f,
475
-                    "Transaction nonce {tx_nonce} must be smaller than the access key nonce upper bound {upper_bound}"
476
-                )
477
-            }
478
-            InvalidTxError::TransactionSizeExceeded { size, limit } => {
479
-                write!(
480
-                    f,
481
-                    "Size of serialized transaction {size} exceeded the limit {limit}"
482
-                )
483
-            }
484
-        }
485
-    }
486
-}
487
-
488
-impl From<InvalidAccessKeyError> for InvalidTxError {
489
-    fn from(error: InvalidAccessKeyError) -> Self {
490
-        InvalidTxError::InvalidAccessKeyError(error)
491
-    }
492
-}
493
-
494
-impl Display for InvalidAccessKeyError {
495
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
496
-        match self {
497
-            InvalidAccessKeyError::AccessKeyNotFound {
498
-                account_id,
499
-                public_key,
500
-            } => write!(
501
-                f,
502
-                "Signer {account_id:?} doesn't have access key with the given public_key {public_key}"
503
-            ),
504
-            InvalidAccessKeyError::ReceiverMismatch {
505
-                tx_receiver,
506
-                ak_receiver,
507
-            } => write!(
508
-                f,
509
-                "Transaction receiver_id {tx_receiver:?} doesn't match the access key receiver_id {ak_receiver:?}",
510
-            ),
511
-            InvalidAccessKeyError::MethodNameMismatch { method_name } => write!(
512
-                f,
513
-                "Transaction method name {method_name:?} isn't allowed by the access key"
514
-            ),
515
-            InvalidAccessKeyError::RequiresFullAccess => {
516
-                write!(f, "Invalid access key type. Full-access keys are required for transactions that have multiple or non-function-call actions")
517
-            }
518
-            InvalidAccessKeyError::NotEnoughAllowance {
519
-                account_id,
520
-                public_key,
521
-                allowance,
522
-                cost,
523
-            } => write!(
524
-                f,
525
-                "Access Key {account_id:?}:{public_key} does not have enough balance {allowance} for transaction costing {cost}"
526
-            ),
527
-            InvalidAccessKeyError::DepositWithFunctionCall => {
528
-                write!(f, "Having a deposit with a function call action is not allowed with a function call access key.")
529
-            }
530
-        }
531
-    }
532
-}
533
-
534
-impl std::error::Error for InvalidAccessKeyError {}
535
-
536
-/// Happens when the input balance doesn't match the output balance in Runtime apply.
537
-#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
538
-pub struct BalanceMismatchError {
539
-    // Input balances
540
-    #[serde(with = "dec_format")]
541
-    pub incoming_validator_rewards: Balance,
542
-    #[serde(with = "dec_format")]
543
-    pub initial_accounts_balance: Balance,
544
-    #[serde(with = "dec_format")]
545
-    pub incoming_receipts_balance: Balance,
546
-    #[serde(with = "dec_format")]
547
-    pub processed_delayed_receipts_balance: Balance,
548
-    #[serde(with = "dec_format")]
549
-    pub initial_postponed_receipts_balance: Balance,
550
-    // Output balances
551
-    #[serde(with = "dec_format")]
552
-    pub final_accounts_balance: Balance,
553
-    #[serde(with = "dec_format")]
554
-    pub outgoing_receipts_balance: Balance,
555
-    #[serde(with = "dec_format")]
556
-    pub new_delayed_receipts_balance: Balance,
557
-    #[serde(with = "dec_format")]
558
-    pub final_postponed_receipts_balance: Balance,
559
-    #[serde(with = "dec_format")]
560
-    pub tx_burnt_amount: Balance,
561
-    #[serde(with = "dec_format")]
562
-    pub slashed_burnt_amount: Balance,
563
-    #[serde(with = "dec_format")]
564
-    pub other_burnt_amount: Balance,
565
-}
566
-
567
-impl Display for BalanceMismatchError {
568
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
569
-        // Using saturating add to avoid overflow in display
570
-        let initial_balance = self
571
-            .incoming_validator_rewards
572
-            .saturating_add(self.initial_accounts_balance)
573
-            .saturating_add(self.incoming_receipts_balance)
574
-            .saturating_add(self.processed_delayed_receipts_balance)
575
-            .saturating_add(self.initial_postponed_receipts_balance);
576
-        let final_balance = self
577
-            .final_accounts_balance
578
-            .saturating_add(self.outgoing_receipts_balance)
579
-            .saturating_add(self.new_delayed_receipts_balance)
580
-            .saturating_add(self.final_postponed_receipts_balance)
581
-            .saturating_add(self.tx_burnt_amount)
582
-            .saturating_add(self.slashed_burnt_amount)
583
-            .saturating_add(self.other_burnt_amount);
584
-        write!(
585
-            f,
586
-            "Balance Mismatch Error. The input balance {} doesn't match output balance {}\n\
587
-             Inputs:\n\
588
-             \tIncoming validator rewards sum: {}\n\
589
-             \tInitial accounts balance sum: {}\n\
590
-             \tIncoming receipts balance sum: {}\n\
591
-             \tProcessed delayed receipts balance sum: {}\n\
592
-             \tInitial postponed receipts balance sum: {}\n\
593
-             Outputs:\n\
594
-             \tFinal accounts balance sum: {}\n\
595
-             \tOutgoing receipts balance sum: {}\n\
596
-             \tNew delayed receipts balance sum: {}\n\
597
-             \tFinal postponed receipts balance sum: {}\n\
598
-             \tTx fees burnt amount: {}\n\
599
-             \tSlashed amount: {}\n\
600
-             \tOther burnt amount: {}",
601
-            initial_balance,
602
-            final_balance,
603
-            self.incoming_validator_rewards,
604
-            self.initial_accounts_balance,
605
-            self.incoming_receipts_balance,
606
-            self.processed_delayed_receipts_balance,
607
-            self.initial_postponed_receipts_balance,
608
-            self.final_accounts_balance,
609
-            self.outgoing_receipts_balance,
610
-            self.new_delayed_receipts_balance,
611
-            self.final_postponed_receipts_balance,
612
-            self.tx_burnt_amount,
613
-            self.slashed_burnt_amount,
614
-            self.other_burnt_amount,
615
-        )
616
-    }
617
-}
618
-
619
-impl std::error::Error for BalanceMismatchError {}
620
-
621
-#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq)]
622
-pub struct IntegerOverflowError;
623
-
624
-impl std::fmt::Display for IntegerOverflowError {
625
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
626
-        f.write_str(&format!("{self:?}"))
627
-    }
628
-}
629
-
630
-impl std::error::Error for IntegerOverflowError {}
631
-
632
-impl From<IntegerOverflowError> for InvalidTxError {
633
-    fn from(_: IntegerOverflowError) -> Self {
634
-        InvalidTxError::CostOverflow
635
-    }
636
-}
637
-
638
-impl From<IntegerOverflowError> for RuntimeError {
639
-    fn from(_: IntegerOverflowError) -> Self {
640
-        RuntimeError::UnexpectedIntegerOverflow
641
-    }
642
-}
643
-
644
-impl From<StorageError> for RuntimeError {
645
-    fn from(e: StorageError) -> Self {
646
-        RuntimeError::StorageError(e)
647
-    }
648
-}
649
-
650
-impl From<BalanceMismatchError> for RuntimeError {
651
-    fn from(e: BalanceMismatchError) -> Self {
652
-        RuntimeError::BalanceMismatchError(e)
653
-    }
654
-}
655
-
656
-impl From<InvalidTxError> for RuntimeError {
657
-    fn from(e: InvalidTxError) -> Self {
658
-        RuntimeError::InvalidTxError(e)
659
-    }
660
-}
661
-
662
-impl From<EpochError> for RuntimeError {
663
-    fn from(e: EpochError) -> Self {
664
-        RuntimeError::ValidatorError(e)
665
-    }
666
-}
667
-
668
-impl Display for ActionError {
669
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
670
-        write!(
671
-            f,
672
-            "Action #{}: {}",
673
-            self.index.unwrap_or_default(),
674
-            self.kind
675
-        )
676
-    }
677
-}
678
-
679
-impl Display for ActionErrorKind {
680
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
681
-        match self {
682
-            ActionErrorKind::AccountAlreadyExists { account_id } => {
683
-                write!(f, "Can't create a new account {account_id:?}, because it already exists")
684
-            }
685
-            ActionErrorKind::AccountDoesNotExist { account_id } => write!(
686
-                f,
687
-                "Can't complete the action because account {account_id:?} doesn't exist"
688
-            ),
689
-            ActionErrorKind::ActorNoPermission { actor_id, account_id } => write!(
690
-                f,
691
-                "Actor {actor_id:?} doesn't have permission to account {account_id:?} to complete the action"
692
-            ),
693
-            ActionErrorKind::LackBalanceForState { account_id, amount } => write!(
694
-                f,
695
-                "The account {account_id} wouldn't have enough balance to cover storage, required to have {amount} yoctoNEAR more"
696
-            ),
697
-            ActionErrorKind::TriesToUnstake { account_id } => {
698
-                write!(f, "Account {account_id:?} is not yet staked, but tries to unstake")
699
-            }
700
-            ActionErrorKind::TriesToStake { account_id, stake, locked, balance } => write!(
701
-                f,
702
-                "Account {account_id:?} tries to stake {stake}, but has staked {locked} and only has {balance}"
703
-            ),
704
-            ActionErrorKind::CreateAccountOnlyByRegistrar { account_id, registrar_account_id, predecessor_id } => write!(
705
-                f,
706
-                "A top-level account ID {account_id:?} can't be created by {predecessor_id:?}, short top-level account IDs can only be created by {registrar_account_id:?}"
707
-            ),
708
-            ActionErrorKind::CreateAccountNotAllowed { account_id, predecessor_id } => write!(
709
-                f,
710
-                "A sub-account ID {account_id:?} can't be created by account {predecessor_id:?}"
711
-            ),
712
-            ActionErrorKind::DeleteKeyDoesNotExist { account_id, .. } => write!(
713
-                f,
714
-                "Account {account_id:?} tries to remove an access key that doesn't exist"
715
-            ),
716
-            ActionErrorKind::AddKeyAlreadyExists { public_key, .. } => write!(
717
-                f,
718
-                "The public key {public_key:?} is already used for an existing access key"
719
-            ),
720
-            ActionErrorKind::DeleteAccountStaking { account_id } => {
721
-                write!(f, "Account {account_id:?} is staking and can not be deleted")
722
-            }
723
-            ActionErrorKind::FunctionCallError(s) => write!(f, "{s:?}"),
724
-            ActionErrorKind::NewReceiptValidationError(e) => {
725
-                write!(f, "An new action receipt created during a FunctionCall is not valid: {e}")
726
-            }
727
-            ActionErrorKind::InsufficientStake { account_id, stake, minimum_stake } => write!(f, "Account {account_id} tries to stake {stake} but minimum required stake is {minimum_stake}"),
728
-            ActionErrorKind::OnlyImplicitAccountCreationAllowed { account_id } => write!(f, "CreateAccount action is called on hex-characters account of length 64 {account_id}"),
729
-            ActionErrorKind::DeleteAccountWithLargeState { account_id } => write!(f, "The state of account {account_id} is too large and therefore cannot be deleted"),
730
-        }
731
-    }
732
-}
733
-
734
-#[derive(Eq, PartialEq, Clone)]
735
-pub enum EpochError {
736
-    /// Error calculating threshold from given stakes for given number of seats.
737
-    /// Only should happened if calling code doesn't check for integer value of stake > number of seats.
738
-    ThresholdError { stake_sum: Balance, num_seats: u64 },
739
-    /// Missing block hash in the storage (means there is some structural issue).
740
-    MissingBlock(CryptoHash),
741
-    /// Error due to IO (DB read/write, serialization, etc.).
742
-    IOErr(String),
743
-    /// Error getting information for a shard
744
-    ShardingError(String),
745
-    NotEnoughValidators {
746
-        num_validators: u64,
747
-        num_shards: u64,
748
-    },
749
-}
750
-
751
-impl std::error::Error for EpochError {}
752
-
753
-impl Display for EpochError {
754
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
755
-        match self {
756
-            EpochError::ThresholdError {
757
-                stake_sum,
758
-                num_seats,
759
-            } => write!(
760
-                f,
761
-                "Total stake {stake_sum} must be higher than the number of seats {num_seats}"
762
-            ),
763
-            EpochError::MissingBlock(hash) => write!(f, "Missing block {hash}"),
764
-            EpochError::IOErr(err) => write!(f, "IO: {err}"),
765
-            EpochError::ShardingError(err) => write!(f, "Sharding Error: {err}"),
766
-            EpochError::NotEnoughValidators {
767
-                num_shards,
768
-                num_validators,
769
-            } => {
770
-                write!(f, "There were not enough validator proposals to fill all shards. num_proposals: {num_validators}, num_shards: {num_shards}")
771
-            }
772
-        }
773
-    }
774
-}
775
-
776
-impl Debug for EpochError {
777
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
778
-        match self {
779
-            EpochError::ThresholdError {
780
-                stake_sum,
781
-                num_seats,
782
-            } => {
783
-                write!(f, "ThresholdError({stake_sum}, {num_seats})")
784
-            }
785
-            EpochError::MissingBlock(hash) => write!(f, "MissingBlock({hash})"),
786
-            EpochError::IOErr(err) => write!(f, "IOErr({err})"),
787
-            EpochError::ShardingError(err) => write!(f, "ShardingError({err})"),
788
-            EpochError::NotEnoughValidators {
789
-                num_shards,
790
-                num_validators,
791
-            } => {
792
-                write!(f, "NotEnoughValidators({num_validators}, {num_shards})")
793
-            }
794
-        }
795
-    }
796
-}
797
-
798
-impl From<std::io::Error> for EpochError {
799
-    fn from(error: std::io::Error) -> Self {
800
-        EpochError::IOErr(error.to_string())
801
-    }
802
-}

+ 0
- 5
near-primitives-light/src/lib.rs View File

@@ -1,5 +0,0 @@
1
-pub mod errors;
2
-pub mod receipt;
3
-pub mod transaction;
4
-pub mod types;
5
-pub mod views;

+ 0
- 179
near-primitives-light/src/receipt.rs View File

@@ -1,179 +0,0 @@
1
-use borsh::{BorshDeserialize, BorshSerialize};
2
-use near_primitives_core::{
3
-    hash::CryptoHash,
4
-    serialize::{dec_format, option_base64_format, to_base58},
5
-    types::{AccountId, Balance, ShardId},
6
-};
7
-use serde::{Deserialize, Serialize};
8
-use std::{borrow::Borrow, collections::HashMap, fmt, hash::Hash};
9
-
10
-use crate::transaction::*;
11
-use common_api::crypto::prelude::*;
12
-
13
-/// Receipts are used for a cross-shard communication.
14
-/// Receipts could be 2 types (determined by a `ReceiptEnum`): `ReceiptEnum::Action` of `ReceiptEnum::Data`.
15
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
16
-pub struct Receipt {
17
-    /// An issuer account_id of a particular receipt.
18
-    /// `predecessor_id` could be either `Transaction` `signer_id` or intermediate contract's `account_id`.
19
-    pub predecessor_id: AccountId,
20
-    /// `receiver_id` is a receipt destination.
21
-    pub receiver_id: AccountId,
22
-    /// An unique id for the receipt
23
-    pub receipt_id: CryptoHash,
24
-    /// A receipt type
25
-    pub receipt: ReceiptEnum,
26
-}
27
-
28
-impl Borrow<CryptoHash> for Receipt {
29
-    fn borrow(&self) -> &CryptoHash {
30
-        &self.receipt_id
31
-    }
32
-}
33
-
34
-impl Receipt {
35
-    /// It's not a content hash, but receipt_id is unique.
36
-    pub fn get_hash(&self) -> CryptoHash {
37
-        self.receipt_id
38
-    }
39
-
40
-    /// Generates a receipt with a transfer from system for a given balance without a receipt_id.
41
-    /// This should be used for token refunds instead of gas refunds. It doesn't refund the
42
-    /// allowance of the access key. For gas refunds use `new_gas_refund`.
43
-    pub fn new_balance_refund(receiver_id: &AccountId, refund: Balance) -> Self {
44
-        Receipt {
45
-            predecessor_id: "system".parse().unwrap(),
46
-            receiver_id: receiver_id.clone(),
47
-            receipt_id: CryptoHash::default(),
48
-
49
-            receipt: ReceiptEnum::Action(ActionReceipt {
50
-                signer_id: "system".parse().unwrap(),
51
-                signer_public_key: Ed25519PublicKey::try_from_bytes(&[0; 32]).unwrap(),
52
-                gas_price: 0,
53
-                output_data_receivers: vec![],
54
-                input_data_ids: vec![],
55
-                actions: vec![Action::Transfer(TransferAction { deposit: refund })],
56
-            }),
57
-        }
58
-    }
59
-
60
-    /// Generates a receipt with a transfer action from system for a given balance without a
61
-    /// receipt_id. It contains `signer_id` and `signer_public_key` to indicate this is a gas
62
-    /// refund. The execution of this receipt will try to refund the allowance of the
63
-    /// access key with the given public key.
64
-    /// NOTE: The access key may be replaced by the owner, so the execution can't rely that the
65
-    /// access key is the same and it should use best effort for the refund.
66
-    pub fn new_gas_refund(
67
-        receiver_id: &AccountId,
68
-        refund: Balance,
69
-        signer_public_key: Ed25519PublicKey,
70
-    ) -> Self {
71
-        Receipt {
72
-            predecessor_id: "system".parse().unwrap(),
73
-            receiver_id: receiver_id.clone(),
74
-            receipt_id: CryptoHash::default(),
75
-
76
-            receipt: ReceiptEnum::Action(ActionReceipt {
77
-                signer_id: receiver_id.clone(),
78
-                signer_public_key,
79
-                gas_price: 0,
80
-                output_data_receivers: vec![],
81
-                input_data_ids: vec![],
82
-                actions: vec![Action::Transfer(TransferAction { deposit: refund })],
83
-            }),
84
-        }
85
-    }
86
-}
87
-
88
-/// Receipt could be either ActionReceipt or DataReceipt
89
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
90
-#[allow(clippy::large_enum_variant)]
91
-pub enum ReceiptEnum {
92
-    Action(ActionReceipt),
93
-    Data(DataReceipt),
94
-}
95
-
96
-/// ActionReceipt is derived from an Action from `Transaction or from Receipt`
97
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
98
-pub struct ActionReceipt {
99
-    /// A signer of the original transaction
100
-    pub signer_id: AccountId,
101
-    /// An access key which was used to sign the original transaction
102
-    pub signer_public_key: Ed25519PublicKey,
103
-    /// A gas_price which has been used to buy gas in the original transaction
104
-    #[serde(with = "dec_format")]
105
-    pub gas_price: Balance,
106
-    /// If present, where to route the output data
107
-    pub output_data_receivers: Vec<DataReceiver>,
108
-    /// A list of the input data dependencies for this Receipt to process.
109
-    /// If all `input_data_ids` for this receipt are delivered to the account
110
-    /// that means we have all the `ReceivedData` input which will be than converted to a
111
-    /// `PromiseResult::Successful(value)` or `PromiseResult::Failed`
112
-    /// depending on `ReceivedData` is `Some(_)` or `None`
113
-    pub input_data_ids: Vec<CryptoHash>,
114
-    /// A list of actions to process when all input_data_ids are filled
115
-    pub actions: Vec<Action>,
116
-}
117
-
118
-/// An incoming (ingress) `DataReceipt` which is going to a Receipt's `receiver` input_data_ids
119
-/// Which will be converted to `PromiseResult::Successful(value)` or `PromiseResult::Failed`
120
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Hash, PartialEq, Eq, Clone)]
121
-pub struct DataReceipt {
122
-    pub data_id: CryptoHash,
123
-    #[serde(with = "option_base64_format")]
124
-    pub data: Option<Vec<u8>>,
125
-}
126
-
127
-impl fmt::Debug for DataReceipt {
128
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129
-        f.debug_struct("DataReceipt")
130
-            .field("data_id", &self.data_id)
131
-            .field(
132
-                "data",
133
-                &format_args!("{:?}", self.data.as_deref().map(to_base58)),
134
-            )
135
-            .finish()
136
-    }
137
-}
138
-
139
-/// The outgoing (egress) data which will be transformed
140
-/// to a `DataReceipt` to be sent to a `receipt.receiver`
141
-#[derive(
142
-    BorshSerialize, BorshDeserialize, Serialize, Deserialize, Hash, Clone, Debug, PartialEq, Eq,
143
-)]
144
-pub struct DataReceiver {
145
-    pub data_id: CryptoHash,
146
-    pub receiver_id: AccountId,
147
-}
148
-
149
-/// A temporary data which is created by processing of DataReceipt
150
-/// stored in a state trie with a key = `account_id` + `data_id` until
151
-/// `input_data_ids` of all incoming Receipts are satisfied
152
-/// None means data retrieval was failed
153
-#[derive(BorshSerialize, BorshDeserialize, Hash, PartialEq, Eq, Clone)]
154
-pub struct ReceivedData {
155
-    pub data: Option<Vec<u8>>,
156
-}
157
-
158
-impl fmt::Debug for ReceivedData {
159
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160
-        f.debug_struct("ReceivedData")
161
-            .field(
162
-                "data",
163
-                &format_args!("{:?}", self.data.as_deref().map(to_base58)),
164
-            )
165
-            .finish()
166
-    }
167
-}
168
-
169
-/// Stores indices for a persistent queue for delayed receipts that didn't fit into a block.
170
-#[derive(Default, BorshSerialize, BorshDeserialize, Clone, PartialEq, Eq, Debug)]
171
-pub struct DelayedReceiptIndices {
172
-    // First inclusive index in the queue.
173
-    pub first_index: u64,
174
-    // Exclusive end index of the queue
175
-    pub next_available_index: u64,
176
-}
177
-
178
-/// Map of shard to list of receipts to send to it.
179
-pub type ReceiptResult = HashMap<ShardId, Vec<Receipt>>;

+ 0
- 401
near-primitives-light/src/transaction.rs View File

@@ -1,401 +0,0 @@
1
-use std::{
2
-    borrow::Borrow,
3
-    fmt,
4
-    hash::{Hash, Hasher},
5
-    str::FromStr,
6
-};
7
-
8
-use borsh::{BorshDeserialize, BorshSerialize};
9
-use common_api::crypto::prelude::*;
10
-use near_primitives_core::{
11
-    account::AccessKey,
12
-    hash::{hash, CryptoHash},
13
-    profile::ProfileData,
14
-    serialize::{base64_format, dec_format, to_base58},
15
-    types::{AccountId, Balance, Gas, Nonce},
16
-};
17
-use serde::{Deserialize, Serialize};
18
-
19
-use crate::errors::TxExecutionError;
20
-
21
-pub type LogEntry = String;
22
-
23
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
24
-pub struct Transaction {
25
-    /// An account on which behalf transaction is signed
26
-    pub signer_id: AccountId,
27
-    /// A public key of the access key which was used to sign an account.
28
-    /// Access key holds permissions for calling certain kinds of actions.
29
-    pub public_key: Ed25519PublicKey,
30
-    /// Nonce is used to determine order of transaction in the pool.
31
-    /// It increments for a combination of `signer_id` and `public_key`
32
-    pub nonce: Nonce,
33
-    /// Receiver account for this transaction
34
-    pub receiver_id: AccountId,
35
-    /// The hash of the block in the blockchain on top of which the given transaction is valid
36
-    pub block_hash: CryptoHash,
37
-    /// A list of actions to be applied
38
-    pub actions: Vec<Action>,
39
-}
40
-
41
-impl Transaction {
42
-    /// Computes a hash of the transaction for signing and size of serialized transaction
43
-    pub fn get_hash_and_size(&self) -> (CryptoHash, u64) {
44
-        let bytes = self.try_to_vec().expect("Failed to deserialize");
45
-        (hash(&bytes), bytes.len() as u64)
46
-    }
47
-}
48
-
49
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
50
-pub enum Action {
51
-    /// Create an (sub)account using a transaction `receiver_id` as an ID for
52
-    /// a new account ID must pass validation rules described here
53
-    /// <http://nomicon.io/Primitives/Account.html>.
54
-    CreateAccount(CreateAccountAction),
55
-    /// Sets a Wasm code to a receiver_id
56
-    DeployContract(DeployContractAction),
57
-    FunctionCall(FunctionCallAction),
58
-    Transfer(TransferAction),
59
-    Stake(StakeAction),
60
-    AddKey(AddKeyAction),
61
-    DeleteKey(DeleteKeyAction),
62
-    DeleteAccount(DeleteAccountAction),
63
-}
64
-
65
-impl Action {
66
-    pub fn get_prepaid_gas(&self) -> Gas {
67
-        match self {
68
-            Action::FunctionCall(a) => a.gas,
69
-            _ => 0,
70
-        }
71
-    }
72
-    pub fn get_deposit_balance(&self) -> Balance {
73
-        match self {
74
-            Action::FunctionCall(a) => a.deposit,
75
-            Action::Transfer(a) => a.deposit,
76
-            _ => 0,
77
-        }
78
-    }
79
-}
80
-
81
-/// Create account action
82
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
83
-pub struct CreateAccountAction {}
84
-
85
-impl From<CreateAccountAction> for Action {
86
-    fn from(create_account_action: CreateAccountAction) -> Self {
87
-        Self::CreateAccount(create_account_action)
88
-    }
89
-}
90
-
91
-/// Deploy contract action
92
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone)]
93
-pub struct DeployContractAction {
94
-    /// WebAssembly binary
95
-    #[serde(with = "base64_format")]
96
-    pub code: Vec<u8>,
97
-}
98
-
99
-impl From<DeployContractAction> for Action {
100
-    fn from(deploy_contract_action: DeployContractAction) -> Self {
101
-        Self::DeployContract(deploy_contract_action)
102
-    }
103
-}
104
-
105
-impl fmt::Debug for DeployContractAction {
106
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107
-        f.debug_struct("DeployContractAction").finish()
108
-    }
109
-}
110
-
111
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone)]
112
-pub struct FunctionCallAction {
113
-    pub method_name: String,
114
-    #[serde(with = "base64_format")]
115
-    pub args: Vec<u8>,
116
-    pub gas: Gas,
117
-    #[serde(with = "dec_format")]
118
-    pub deposit: Balance,
119
-}
120
-
121
-impl From<FunctionCallAction> for Action {
122
-    fn from(function_call_action: FunctionCallAction) -> Self {
123
-        Self::FunctionCall(function_call_action)
124
-    }
125
-}
126
-
127
-impl fmt::Debug for FunctionCallAction {
128
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129
-        f.debug_struct("FunctionCallAction")
130
-            .field("method_name", &format_args!("{}", &self.method_name))
131
-            .field("args", &format_args!("{}", to_base58(&self.args)))
132
-            .field("gas", &format_args!("{}", &self.gas))
133
-            .field("deposit", &format_args!("{}", &self.deposit))
134
-            .finish()
135
-    }
136
-}
137
-
138
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
139
-pub struct TransferAction {
140
-    #[serde(with = "dec_format")]
141
-    pub deposit: Balance,
142
-}
143
-
144
-impl From<TransferAction> for Action {
145
-    fn from(transfer_action: TransferAction) -> Self {
146
-        Self::Transfer(transfer_action)
147
-    }
148
-}
149
-
150
-/// An action which stakes signer_id tokens and setup's validator public key
151
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
152
-pub struct StakeAction {
153
-    /// Amount of tokens to stake.
154
-    #[serde(with = "dec_format")]
155
-    pub stake: Balance,
156
-    /// Validator key which will be used to sign transactions on behalf of signer_id
157
-    pub public_key: Ed25519PublicKey,
158
-}
159
-
160
-impl From<StakeAction> for Action {
161
-    fn from(stake_action: StakeAction) -> Self {
162
-        Self::Stake(stake_action)
163
-    }
164
-}
165
-
166
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
167
-pub struct AddKeyAction {
168
-    /// A public key which will be associated with an access_key
169
-    pub public_key: Ed25519PublicKey,
170
-    /// An access key with the permission
171
-    pub access_key: AccessKey,
172
-}
173
-
174
-impl From<AddKeyAction> for Action {
175
-    fn from(add_key_action: AddKeyAction) -> Self {
176
-        Self::AddKey(add_key_action)
177
-    }
178
-}
179
-
180
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
181
-pub struct DeleteKeyAction {
182
-    /// A public key associated with the access_key to be deleted.
183
-    pub public_key: Ed25519PublicKey,
184
-}
185
-
186
-impl From<DeleteKeyAction> for Action {
187
-    fn from(delete_key_action: DeleteKeyAction) -> Self {
188
-        Self::DeleteKey(delete_key_action)
189
-    }
190
-}
191
-
192
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
193
-pub struct DeleteAccountAction {
194
-    pub beneficiary_id: AccountId,
195
-}
196
-
197
-impl From<DeleteAccountAction> for Action {
198
-    fn from(delete_account_action: DeleteAccountAction) -> Self {
199
-        Self::DeleteAccount(delete_account_action)
200
-    }
201
-}
202
-
203
-#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Eq, Debug, Clone)]
204
-#[borsh_init(init)]
205
-pub struct SignedTransaction {
206
-    pub transaction: Transaction,
207
-    pub signature: Ed25519Signature,
208
-    #[borsh_skip]
209
-    hash: CryptoHash,
210
-    #[borsh_skip]
211
-    size: u64,
212
-}
213
-
214
-impl SignedTransaction {
215
-    pub fn new(signature: Ed25519Signature, transaction: Transaction) -> Self {
216
-        let mut signed_tx = Self {
217
-            signature,
218
-            transaction,
219
-            hash: CryptoHash::default(),
220
-            size: u64::default(),
221
-        };
222
-        signed_tx.init();
223
-        signed_tx
224
-    }
225
-
226
-    pub fn init(&mut self) {
227
-        let (hash, size) = self.transaction.get_hash_and_size();
228
-        self.hash = hash;
229
-        self.size = size;
230
-    }
231
-
232
-    pub fn get_hash(&self) -> CryptoHash {
233
-        self.hash
234
-    }
235
-
236
-    pub fn get_size(&self) -> u64 {
237
-        self.size
238
-    }
239
-}
240
-
241
-impl Hash for SignedTransaction {
242
-    fn hash<H: Hasher>(&self, state: &mut H) {
243
-        self.hash.hash(state)
244
-    }
245
-}
246
-
247
-impl PartialEq for SignedTransaction {
248
-    fn eq(&self, other: &SignedTransaction) -> bool {
249
-        self.hash == other.hash && self.signature == other.signature
250
-    }
251
-}
252
-
253
-impl Borrow<CryptoHash> for SignedTransaction {
254
-    fn borrow(&self) -> &CryptoHash {
255
-        &self.hash
256
-    }
257
-}
258
-
259
-/// The status of execution for a transaction or a receipt.
260
-#[derive(Default, BorshSerialize, BorshDeserialize, PartialEq, Eq, Clone)]
261
-pub enum ExecutionStatus {
262
-    /// The execution is pending or unknown.
263
-    #[default]
264
-    Unknown,
265
-    /// The execution has failed with the given execution error.
266
-    Failure(Box<TxExecutionError>),
267
-    /// The final action succeeded and returned some value or an empty vec.
268
-    SuccessValue(Vec<u8>),
269
-    /// The final action of the receipt returned a promise or the signed transaction was converted
270
-    /// to a receipt. Contains the receipt_id of the generated receipt.
271
-    SuccessReceiptId(CryptoHash),
272
-}
273
-
274
-impl fmt::Debug for ExecutionStatus {
275
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276
-        match self {
277
-            ExecutionStatus::Unknown => f.write_str("Unknown"),
278
-            ExecutionStatus::Failure(e) => f.write_fmt(format_args!("Failure({e})")),
279
-            ExecutionStatus::SuccessValue(v) => {
280
-                f.write_fmt(format_args!("SuccessValue({})", to_base58(v)))
281
-            }
282
-            ExecutionStatus::SuccessReceiptId(receipt_id) => {
283
-                f.write_fmt(format_args!("SuccessReceiptId({receipt_id})"))
284
-            }
285
-        }
286
-    }
287
-}
288
-
289
-/// ExecutionOutcome for proof. Excludes logs and metadata
290
-#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Clone)]
291
-pub struct PartialExecutionOutcome {
292
-    pub receipt_ids: Vec<CryptoHash>,
293
-    pub gas_burnt: Gas,
294
-    pub tokens_burnt: Balance,
295
-    pub executor_id: AccountId,
296
-    pub status: PartialExecutionStatus,
297
-}
298
-
299
-impl From<&ExecutionOutcome> for PartialExecutionOutcome {
300
-    fn from(outcome: &ExecutionOutcome) -> Self {
301
-        Self {
302
-            receipt_ids: outcome.receipt_ids.clone(),
303
-            gas_burnt: outcome.gas_burnt,
304
-            tokens_burnt: outcome.tokens_burnt,
305
-            executor_id: outcome.executor_id.clone(),
306
-            status: outcome.status.clone().into(),
307
-        }
308
-    }
309
-}
310
-
311
-/// ExecutionStatus for proof. Excludes failure debug info.
312
-#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Clone)]
313
-pub enum PartialExecutionStatus {
314
-    Unknown,
315
-    Failure,
316
-    SuccessValue(Vec<u8>),
317
-    SuccessReceiptId(CryptoHash),
318
-}
319
-
320
-impl From<ExecutionStatus> for PartialExecutionStatus {
321
-    fn from(status: ExecutionStatus) -> PartialExecutionStatus {
322
-        match status {
323
-            ExecutionStatus::Unknown => PartialExecutionStatus::Unknown,
324
-            ExecutionStatus::Failure(_) => PartialExecutionStatus::Failure,
325
-            ExecutionStatus::SuccessValue(value) => PartialExecutionStatus::SuccessValue(value),
326
-            ExecutionStatus::SuccessReceiptId(id) => PartialExecutionStatus::SuccessReceiptId(id),
327
-        }
328
-    }
329
-}
330
-
331
-/// Execution outcome for one signed transaction or one receipt.
332
-#[derive(BorshSerialize, BorshDeserialize, PartialEq, Clone, Eq)]
333
-pub struct ExecutionOutcome {
334
-    /// Logs from this transaction or receipt.
335
-    pub logs: Vec<LogEntry>,
336
-    /// Receipt IDs generated by this transaction or receipt.
337
-    pub receipt_ids: Vec<CryptoHash>,
338
-    /// The amount of the gas burnt by the given transaction or receipt.
339
-    pub gas_burnt: Gas,
340
-    /// The amount of tokens burnt corresponding to the burnt gas amount.
341
-    /// This value doesn't always equal to the `gas_burnt` multiplied by the gas price, because
342
-    /// the prepaid gas price might be lower than the actual gas price and it creates a deficit.
343
-    pub tokens_burnt: Balance,
344
-    /// The id of the account on which the execution happens. For transaction this is signer_id,
345
-    /// for receipt this is receiver_id.
346
-    pub executor_id: AccountId,
347
-    /// Execution status. Contains the result in case of successful execution.
348
-    /// NOTE: Should be the latest field since it contains unparsable by light client
349
-    /// ExecutionStatus::Failure
350
-    pub status: ExecutionStatus,
351
-    /// Execution metadata, versioned
352
-    pub metadata: ExecutionMetadata,
353
-}
354
-
355
-impl Default for ExecutionOutcome {
356
-    fn default() -> Self {
357
-        Self {
358
-            logs: Default::default(),
359
-            receipt_ids: Default::default(),
360
-            gas_burnt: Default::default(),
361
-            tokens_burnt: Default::default(),
362
-            executor_id: AccountId::from_str("test").unwrap(),
363
-            status: Default::default(),
364
-            metadata: Default::default(),
365
-        }
366
-    }
367
-}
368
-
369
-#[derive(Default, BorshSerialize, BorshDeserialize, PartialEq, Clone, Eq, Debug)]
370
-pub enum ExecutionMetadata {
371
-    // V1: Empty Metadata
372
-    #[default]
373
-    V1,
374
-
375
-    // V2: With ProfileData
376
-    V2(ProfileData),
377
-}
378
-
379
-impl fmt::Debug for ExecutionOutcome {
380
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
381
-        f.debug_struct("ExecutionOutcome")
382
-            .field("logs", &self.logs)
383
-            .field("receipt_ids", &self.receipt_ids)
384
-            .field("burnt_gas", &self.gas_burnt)
385
-            .field("tokens_burnt", &self.tokens_burnt)
386
-            .field("status", &self.status)
387
-            .field("metadata", &self.metadata)
388
-            .finish()
389
-    }
390
-}
391
-
392
-/// Execution outcome with the identifier.
393
-/// For a signed transaction, the ID is the hash of the transaction.
394
-/// For a receipt, the ID is the receipt ID.
395
-#[derive(PartialEq, Clone, Default, Debug, BorshSerialize, BorshDeserialize, Eq)]
396
-pub struct ExecutionOutcomeWithId {
397
-    /// The transaction hash or the receipt ID.
398
-    pub id: CryptoHash,
399
-    /// Should be the latest field since contains unparsable by light client ExecutionStatus::Failure
400
-    pub outcome: ExecutionOutcome,
401
-}

+ 0
- 231
near-primitives-light/src/types.rs View File

@@ -1,231 +0,0 @@
1
-use borsh::{BorshDeserialize, BorshSerialize};
2
-use common_api::crypto::prelude::*;
3
-use near_primitives_core::{
4
-    account::{AccessKey, Account},
5
-    hash::CryptoHash,
6
-    serialize::dec_format,
7
-    types::*,
8
-};
9
-use serde::{Deserialize, Serialize};
10
-
11
-/// Hash used by to store state root.
12
-pub type StateRoot = CryptoHash;
13
-
14
-/// Different types of finality.
15
-#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
16
-pub enum Finality {
17
-    #[serde(rename = "optimistic")]
18
-    None,
19
-    #[serde(rename = "near-final")]
20
-    DoomSlug,
21
-    #[default]
22
-    #[serde(rename = "final")]
23
-    Final,
24
-}
25
-
26
-#[derive(Debug, Serialize, Deserialize)]
27
-pub struct AccountWithPublicKey {
28
-    pub account_id: AccountId,
29
-    pub public_key: Ed25519PublicKey,
30
-}
31
-
32
-/// Account info for validators
33
-#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
34
-pub struct AccountInfo {
35
-    pub account_id: AccountId,
36
-    pub public_key: Ed25519PublicKey,
37
-    #[serde(with = "dec_format")]
38
-    pub amount: Balance,
39
-}
40
-
41
-/// This type is used to mark function arguments.
42
-///
43
-/// NOTE: The main reason for this to exist (except the type-safety) is that the value is
44
-/// transparently serialized and deserialized as a base64-encoded string when serde is used
45
-/// (serde_json).
46
-#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
47
-pub struct FunctionArgs(Vec<u8>);
48
-
49
-/// A structure used to indicate the kind of state changes due to transaction/receipt processing, etc.
50
-#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
51
-pub enum StateChangeKind {
52
-    AccountTouched { account_id: AccountId },
53
-    AccessKeyTouched { account_id: AccountId },
54
-    DataTouched { account_id: AccountId },
55
-    ContractCodeTouched { account_id: AccountId },
56
-}
57
-
58
-pub type StateChangesKinds = Vec<StateChangeKind>;
59
-
60
-/// A structure used to index state changes due to transaction/receipt processing and other things.
61
-#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
62
-pub enum StateChangeCause {
63
-    /// A type of update that does not get finalized. Used for verification and execution of
64
-    /// immutable smart contract methods. Attempt fo finalize a `TrieUpdate` containing such
65
-    /// change will lead to panic.
66
-    NotWritableToDisk,
67
-    /// A type of update that is used to mark the initial storage update, e.g. during genesis
68
-    /// or in tests setup.
69
-    InitialState,
70
-    /// Processing of a transaction.
71
-    TransactionProcessing { tx_hash: CryptoHash },
72
-    /// Before the receipt is going to be processed, inputs get drained from the state, which
73
-    /// causes state modification.
74
-    ActionReceiptProcessingStarted { receipt_hash: CryptoHash },
75
-    /// Computation of gas reward.
76
-    ActionReceiptGasReward { receipt_hash: CryptoHash },
77
-    /// Processing of a receipt.
78
-    ReceiptProcessing { receipt_hash: CryptoHash },
79
-    /// The given receipt was postponed. This is either a data receipt or an action receipt.
80
-    /// A `DataReceipt` can be postponed if the corresponding `ActionReceipt` is not received yet,
81
-    /// or other data dependencies are not satisfied.
82
-    /// An `ActionReceipt` can be postponed if not all data dependencies are received.
83
-    PostponedReceipt { receipt_hash: CryptoHash },
84
-    /// Updated delayed receipts queue in the state.
85
-    /// We either processed previously delayed receipts or added more receipts to the delayed queue.
86
-    UpdatedDelayedReceipts,
87
-    /// State change that happens when we update validator accounts. Not associated with with any
88
-    /// specific transaction or receipt.
89
-    ValidatorAccountsUpdate,
90
-    /// State change that is happens due to migration that happens in first block of an epoch
91
-    /// after protocol upgrade
92
-    Migration,
93
-    /// State changes for building states for re-sharding
94
-    Resharding,
95
-}
96
-
97
-/// This represents the committed changes in the Trie with a change cause.
98
-#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
99
-pub struct RawStateChange {
100
-    pub cause: StateChangeCause,
101
-    pub data: Option<Vec<u8>>,
102
-}
103
-
104
-#[derive(Debug)]
105
-pub enum StateChangesRequest {
106
-    AccountChanges { account_ids: Vec<AccountId> },
107
-    SingleAccessKeyChanges { keys: Vec<AccountWithPublicKey> },
108
-    AllAccessKeyChanges { account_ids: Vec<AccountId> },
109
-    ContractCodeChanges { account_ids: Vec<AccountId> },
110
-}
111
-
112
-#[derive(Debug)]
113
-pub enum StateChangeValue {
114
-    AccountUpdate {
115
-        account_id: AccountId,
116
-        account: Account,
117
-    },
118
-    AccountDeletion {
119
-        account_id: AccountId,
120
-    },
121
-    AccessKeyUpdate {
122
-        account_id: AccountId,
123
-        public_key: Ed25519PublicKey,
124
-        access_key: AccessKey,
125
-    },
126
-    AccessKeyDeletion {
127
-        account_id: AccountId,
128
-        public_key: Ed25519PublicKey,
129
-    },
130
-    ContractCodeUpdate {
131
-        account_id: AccountId,
132
-        code: Vec<u8>,
133
-    },
134
-    ContractCodeDeletion {
135
-        account_id: AccountId,
136
-    },
137
-}
138
-
139
-impl StateChangeValue {
140
-    pub fn affected_account_id(&self) -> &AccountId {
141
-        match &self {
142
-            StateChangeValue::AccountUpdate { account_id, .. }
143
-            | StateChangeValue::AccountDeletion { account_id }
144
-            | StateChangeValue::AccessKeyUpdate { account_id, .. }
145
-            | StateChangeValue::AccessKeyDeletion { account_id, .. }
146
-            | StateChangeValue::ContractCodeUpdate { account_id, .. }
147
-            | StateChangeValue::ContractCodeDeletion { account_id } => account_id,
148
-        }
149
-    }
150
-}
151
-
152
-#[derive(Debug)]
153
-pub struct StateChangeWithCause {
154
-    pub cause: StateChangeCause,
155
-    pub value: StateChangeValue,
156
-}
157
-
158
-pub type StateChanges = Vec<StateChangeWithCause>;
159
-
160
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
161
-#[serde(untagged)]
162
-pub enum BlockId {
163
-    Height(BlockHeight),
164
-    Hash(CryptoHash),
165
-}
166
-
167
-pub type MaybeBlockId = Option<BlockId>;
168
-
169
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
170
-#[serde(rename_all = "snake_case")]
171
-pub enum SyncCheckpoint {
172
-    Genesis,
173
-    EarliestAvailable,
174
-}
175
-
176
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
177
-#[serde(rename_all = "snake_case")]
178
-pub enum BlockReference {
179
-    BlockId(BlockId),
180
-    Finality(Finality),
181
-    SyncCheckpoint(SyncCheckpoint),
182
-}
183
-
184
-impl BlockReference {
185
-    pub fn latest() -> Self {
186
-        Self::Finality(Finality::None)
187
-    }
188
-}
189
-
190
-impl From<BlockId> for BlockReference {
191
-    fn from(block_id: BlockId) -> Self {
192
-        Self::BlockId(block_id)
193
-    }
194
-}
195
-
196
-impl From<Finality> for BlockReference {
197
-    fn from(finality: Finality) -> Self {
198
-        Self::Finality(finality)
199
-    }
200
-}
201
-
202
-#[derive(Default, BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq, Eq)]
203
-pub struct ValidatorStats {
204
-    pub produced: NumBlocks,
205
-    pub expected: NumBlocks,
206
-}
207
-
208
-#[derive(Debug, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
209
-pub struct BlockChunkValidatorStats {
210
-    pub block_stats: ValidatorStats,
211
-    pub chunk_stats: ValidatorStats,
212
-}
213
-
214
-#[derive(Serialize, Deserialize, Clone, Debug)]
215
-#[serde(tag = "type", rename_all = "snake_case")]
216
-pub enum TransactionOrReceiptId {
217
-    Transaction {
218
-        transaction_hash: CryptoHash,
219
-        sender_id: AccountId,
220
-    },
221
-    Receipt {
222
-        receipt_id: CryptoHash,
223
-        receiver_id: AccountId,
224
-    },
225
-}
226
-
227
-#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
228
-pub enum CompiledContract {
229
-    CompileModuleError,
230
-    Code(Vec<u8>),
231
-}

+ 0
- 1044
near-primitives-light/src/views.rs
File diff suppressed because it is too large
View File


+ 0
- 33
near-rpc/Cargo.toml View File

@@ -1,33 +0,0 @@
1
-[package]
2
-name = "near-rpc"
3
-version = "0.1.0"
4
-edition = "2021"
5
-authors = ["silvestr@relayz.io", "kyrylo@relayz.io"]
6
-description = """
7
-The basic implementation of NEAR RPC.
8
-"""
9
-
10
-[dependencies]
11
-base64 = { version = "0.20" }
12
-bs58 = "0.4"
13
-borsh = "0.9"
14
-common-api = { path = "../common-api" }
15
-itertools = "0.10"
16
-near-primitives-light = { path = "../near-primitives-light" }
17
-near-primitives-core = "0.15"
18
-near-units = "0.2"
19
-reqwest = { version = "0.11", features = ["json"] }
20
-serde = { version = "1", default-features = false, features = ["derive"] }
21
-serde_json = { version = "1", default-features = false }
22
-thiserror = "1"
23
-url = "2"
24
-
25
-[dev-dependencies]
26
-reqwest = { version = "0.11", features = ["json"] }
27
-rand = "0.8.5"
28
-rand_chacha = "0.3"
29
-tempfile = "3"
30
-tokio = { version = "1.2.1", features = ["full"] }
31
-workspaces = { git = "https://github.com/near/workspaces-rs.git", features = [
32
-    "unstable",
33
-] }

+ 0
- 496
near-rpc/src/client.rs View File

@@ -1,496 +0,0 @@
1
-use near_primitives_light::{
2
-    transaction::{
3
-        Action, AddKeyAction, CreateAccountAction, DeleteAccountAction, DeployContractAction,
4
-        FunctionCallAction, TransferAction,
5
-    },
6
-    types::Finality,
7
-    views::{
8
-        BlockView, ExecutionOutcomeWithIdView, FinalExecutionOutcomeView, FinalExecutionStatus,
9
-    },
10
-};
11
-
12
-use near_primitives_core::{
13
-    account::{id::AccountId, AccessKey, AccessKeyPermission},
14
-    hash::CryptoHash,
15
-    types::{Balance, Gas, Nonce},
16
-};
17
-
18
-use crate::{
19
-    rpc::{client::RpcClient, Error as RpcError, NearError},
20
-    utils::{
21
-        extract_logs, serialize_arguments, serialize_transaction, CallResult, TransactionInfo,
22
-        ViewAccessKey, ViewResult,
23
-    },
24
-    Error, Result,
25
-};
26
-
27
-use common_api::crypto::prelude::*;
28
-use serde::de::DeserializeOwned;
29
-use serde_json::{json, Value};
30
-use url::Url;
31
-
32
-use std::{
33
-    ops::Deref,
34
-    sync::{
35
-        atomic::{AtomicU64, Ordering},
36
-        Arc,
37
-    },
38
-};
39
-
40
-type AtomicNonce = Arc<AtomicU64>;
41
-/// Used for signing a transactions
42
-pub struct Signer {
43
-    keypair: Keypair,
44
-    account_id: AccountId,
45
-    nonce: AtomicNonce,
46
-}
47
-
48
-impl Signer {
49
-    #[allow(clippy::result_large_err)]
50
-    pub fn from_secret_str(secret_key: &str, account_id: AccountId, nonce: Nonce) -> Result<Self> {
51
-        Ok(Self {
52
-            keypair: Keypair::from_expanded_secret(secret_key).map_err(Error::CreateSigner)?,
53
-            account_id,
54
-            nonce: AtomicNonce::new(AtomicU64::new(nonce)),
55
-        })
56
-    }
57
-
58
-    pub fn from_secret(secret_key: Ed25519SecretKey, account_id: AccountId, nonce: Nonce) -> Self {
59
-        Self {
60
-            keypair: Keypair::new(secret_key),
61
-            account_id,
62
-            nonce: AtomicNonce::new(AtomicU64::new(nonce)),
63
-        }
64
-    }
65
-
66
-    /// Sign a transaction
67
-    ///
68
-    /// Arguments
69
-    ///
70
-    /// - data - Serialized transaction with a [Borsh](https://borsh.io/)
71
-    pub fn sign(&self, data: &[u8]) -> Ed25519Signature {
72
-        self.keypair.sign(data)
73
-    }
74
-
75
-    pub fn public_key(&self) -> &Ed25519PublicKey {
76
-        self.keypair.public_key()
77
-    }
78
-
79
-    pub fn secret_key(&self) -> &Ed25519SecretKey {
80
-        self.keypair.secret_key()
81
-    }
82
-
83
-    pub fn account(&self) -> &AccountId {
84
-        &self.account_id
85
-    }
86
-
87
-    pub fn nonce(&self) -> Nonce {
88
-        self.nonce.load(Ordering::Acquire)
89
-    }
90
-
91
-    pub fn update_nonce(&self, nonce: Nonce) {
92
-        self.nonce.store(nonce, Ordering::Release);
93
-    }
94
-
95
-    pub fn increment_nonce(&self, value: u64) {
96
-        self.nonce.fetch_add(value, Ordering::AcqRel);
97
-    }
98
-}
99
-
100
-pub struct NearClient {
101
-    pub(crate) rpc_client: RpcClient,
102
-}
103
-
104
-impl NearClient {
105
-    #[allow(clippy::result_large_err)]
106
-    pub fn new(url: Url) -> Result<Self> {
107
-        Ok(Self {
108
-            rpc_client: RpcClient::new(url).map_err(Error::CreateClient)?,
109
-        })
110
-    }
111
-
112
-    /// Queries network and returns block for given height or hash
113
-    pub async fn block(&self, finality: Finality) -> Result<CryptoHash> {
114
-        self.rpc_client
115
-            .request("block", Some(json!({ "finality": finality })))
116
-            .await
117
-            .map_err(Error::BlockCall)
118
-            .and_then(|block_res| {
119
-                serde_json::from_value::<BlockView>(block_res).map_err(Error::DeserializeBlock)
120
-            })
121
-            .map(|block_view| block_view.header.hash)
122
-    }
123
-
124
-    /// Allows you to call a contract method as a view function.
125
-    ///
126
-    /// Arguments
127
-    ///
128
-    /// - contract_id - The [`AccountId`] where smart contract is located
129
-    /// - finality - [`Finality`]
130
-    /// - method - Function that is declared in a smart contract
131
-    /// - args - Function arguments, could be empty
132
-    pub async fn view<'a, T: DeserializeOwned>(
133
-        &'a self,
134
-        contract_id: &'a AccountId,
135
-        finality: Finality,
136
-        method: &'static str,
137
-        args: Option<Value>,
138
-    ) -> Result<ViewOutput<T>> {
139
-        self.rpc_client
140
-            .request(
141
-                "query",
142
-                Some(json!({
143
-                    "request_type": "call_function",
144
-                    "finality": finality,
145
-                    "account_id": contract_id,
146
-                    "method_name": method,
147
-                    "args_base64": base64::encode(serialize_arguments(args)?)
148
-                })),
149
-            )
150
-            .await
151
-            .map_err(Error::ViewCall)
152
-            .and_then(|it| {
153
-                serde_json::from_value::<ViewResult>(it).map_err(Error::DeserializeViewCall)
154
-            })
155
-            .and_then(|view_res| match view_res.result {
156
-                CallResult::Ok(data) => Ok(ViewOutput {
157
-                    logs: view_res.logs,
158
-                    data: serde_json::from_slice(&data).map_err(Error::DeserializeResponseView)?,
159
-                }),
160
-                CallResult::Err(cause) => Err(Error::ViewCall(RpcError::NearProtocol(
161
-                    NearError::new_simple(cause),
162
-                ))),
163
-            })
164
-    }
165
-
166
-    /// Returns information about a single access key for given account
167
-    ///
168
-    /// Arguments
169
-    ///
170
-    /// - account_id - The user [`AccountId`] in a Near network
171
-    /// - public_key - The user [`Ed25519PublicKey`] in a Near network
172
-    pub async fn view_access_key<'a>(
173
-        &'a self,
174
-        account_id: &'a AccountId,
175
-        public_key: &'a Ed25519PublicKey,
176
-        finality: Finality,
177
-    ) -> Result<ViewAccessKey> {
178
-        self.rpc_client
179
-            .request(
180
-                "query",
181
-                Some(json!({
182
-                    "request_type": "view_access_key",
183
-                    "finality": finality,
184
-                    "account_id": account_id,
185
-                    "public_key": public_key,
186
-                })),
187
-            )
188
-            .await
189
-            .map_err(Error::ViewAccessKeyCall)
190
-            .and_then(|it| {
191
-                serde_json::from_value::<ViewAccessKey>(it)
192
-                    .map_err(Error::DeserializeAccessKeyViewCall)
193
-            })
194
-    }
195
-
196
-    /// Queries status of a transaction by hash,
197
-    /// returning the final transaction result and details of all receipts.
198
-    ///
199
-    /// Arguments
200
-    ///
201
-    /// - transaction_id - Transaction [`CryptoHash`]
202
-    /// - signer - [`Signer`] that contain information regarding user [`Keypair`]
203
-    ///
204
-    /// Return
205
-    ///
206
-    /// If a transaction still processing will be returned an error [`Error::ViewTransaction`],
207
-    /// in this case can try to execute [`view_transaction`] one more time, or a several times.
208
-    /// If an error differs from [`Error::ViewTransaction`] that something goes totally wrong and
209
-    /// you should stop to try executing [`view_transaction`] with the same arguments/signer
210
-    pub async fn view_transaction<'a>(
211
-        &'a self,
212
-        transaction_id: &'a CryptoHash,
213
-        signer: &'a Signer,
214
-    ) -> Result<Output> {
215
-        let params = Value::Array(vec![
216
-            serde_json::to_value(transaction_id)
217
-                .map_err(|err| Error::SerializeTxViewArg("transaction_id", err))?,
218
-            serde_json::to_value(signer.account())
219
-                .map_err(|err| Error::SerializeTxViewArg("signer_acc_id", err))?,
220
-        ]);
221
-
222
-        let execution_outcome = self
223
-            .rpc_client
224
-            .request("EXPERIMENTAL_tx_status", Some(params))
225
-            .await
226
-            .map_err(Error::ViewTransaction)
227
-            .and_then(|execution_outcome| {
228
-                serde_json::from_value::<FinalExecutionOutcomeView>(execution_outcome)
229
-                    .map_err(Error::DeserializeExecutionOutcome)
230
-            })?;
231
-
232
-        proceed_outcome(signer, execution_outcome)
233
-    }
234
-
235
-    /// Execute a transaction with a function call to the smart contract
236
-    ///
237
-    /// Arguments
238
-    ///
239
-    /// - signer - Transaction [`Signer`]
240
-    /// - contract_id - The [`AccountId`] where smart contract is located
241
-    /// - method - Function that is declared in a smart contract (Arguments fir function call provided later in a [`FunctionCallBuilder`])
242
-    pub fn function_call<'a>(
243
-        &'a self,
244
-        signer: &'a Signer,
245
-        contract_id: &'a AccountId,
246
-        method: &'static str,
247
-    ) -> FunctionCallBuilder {
248
-        let transaction_info = TransactionInfo::new(self, signer, contract_id);
249
-        FunctionCallBuilder::new(transaction_info, method)
250
-    }
251
-
252
-    pub fn deploy_contract<'a>(
253
-        &'a self,
254
-        signer: &'a Signer,
255
-        contract_id: &'a AccountId,
256
-        wasm: Vec<u8>,
257
-    ) -> FunctionCall {
258
-        FunctionCall {
259
-            info: TransactionInfo::new(self, signer, contract_id),
260
-            actions: vec![Action::from(DeployContractAction { code: wasm })],
261
-        }
262
-    }
263
-
264
-    pub fn create_account<'a>(
265
-        &'a self,
266
-        signer: &'a Signer,
267
-        new_account_id: &'a AccountId,
268
-        new_account_pk: Ed25519PublicKey,
269
-        amount: Balance,
270
-    ) -> FunctionCall {
271
-        let info = TransactionInfo::new(self, signer, new_account_id);
272
-        let actions = vec![
273
-            CreateAccountAction {}.into(),
274
-            AddKeyAction {
275
-                public_key: new_account_pk,
276
-                access_key: AccessKey {
277
-                    nonce: 0,
278
-                    permission: AccessKeyPermission::FullAccess,
279
-                },
280
-            }
281
-            .into(),
282
-            TransferAction { deposit: amount }.into(),
283
-        ];
284
-
285
-        FunctionCall { info, actions }
286
-    }
287
-
288
-    pub fn delete_account<'a>(
289
-        &'a self,
290
-        signer: &'a Signer,
291
-        account_id: &'a AccountId,
292
-        beneficiary_acc_id: &'a AccountId,
293
-    ) -> FunctionCall {
294
-        let info = TransactionInfo::new(self, signer, account_id);
295
-        let actions = vec![DeleteAccountAction {
296
-            beneficiary_id: beneficiary_acc_id.clone(),
297
-        }
298
-        .into()];
299
-
300
-        FunctionCall { info, actions }
301
-    }
302
-}
303
-
304
-#[derive(Debug)]
305
-pub struct ViewOutput<T: DeserializeOwned> {
306
-    logs: Vec<String>,
307
-    data: T,
308
-}
309
-
310
-impl<T: DeserializeOwned> ViewOutput<T> {
311
-    /// Logs from view call
312
-    pub fn logs(&self) -> Vec<String> {
313
-        self.logs.clone()
314
-    }
315
-
316
-    /// Return a view call result
317
-    pub fn data(self) -> T {
318
-        self.data
319
-    }
320
-}
321
-
322
-impl<T: DeserializeOwned> Deref for ViewOutput<T> {
323
-    type Target = T;
324
-
325
-    fn deref(&self) -> &Self::Target {
326
-        &self.data
327
-    }
328
-}
329
-
330
-/// Function call output.
331
-#[derive(Debug)]
332
-pub struct Output {
333
-    transaction: ExecutionOutcomeWithIdView,
334
-    logs: Vec<String>,
335
-    data: Vec<u8>,
336
-}
337
-
338
-impl Output {
339
-    #[allow(clippy::result_large_err)]
340
-    /// If function don't return anything it will return [`Error::DeserializeTransactionOutput`]
341
-    /// Or if you miss matching a return type
342
-    pub fn output<T: DeserializeOwned>(&self) -> Result<T> {
343
-        serde_json::from_slice::<T>(&self.data).map_err(Error::DeserializeTransactionOutput)
344
-    }
345
-
346
-    #[allow(clippy::misnamed_getters)]
347
-    /// Returns a transaction id
348
-    pub fn id(&self) -> CryptoHash {
349
-        self.transaction.block_hash
350
-    }
351
-
352
-    /// Amount of gas that was burnt during transaction execution
353
-    pub fn gas_burnt(&self) -> Gas {
354
-        self.transaction.outcome.gas_burnt
355
-    }
356
-
357
-    /// Logs that smart contract produced
358
-    pub fn logs(&self) -> Vec<String> {
359
-        self.logs.clone()
360
-    }
361
-}
362
-
363
-pub struct FunctionCallBuilder<'a> {
364
-    info: TransactionInfo<'a>,
365
-    deposit: Balance,
366
-    gas: Gas,
367
-    args: Option<Value>,
368
-    method_name: &'a str,
369
-}
370
-
371
-impl<'a> FunctionCallBuilder<'a> {
372
-    fn new(info: TransactionInfo<'a>, method_name: &'a str) -> Self {
373
-        Self {
374
-            info,
375
-            method_name,
376
-            gas: Default::default(),
377
-            args: Default::default(),
378
-            deposit: Default::default(),
379
-        }
380
-    }
381
-
382
-    pub fn deposit(mut self, deposit: Balance) -> Self {
383
-        self.deposit = deposit;
384
-        self
385
-    }
386
-
387
-    /// Amount of gas that will be hold for function execution
388
-    pub fn gas(mut self, gas: Gas) -> Self {
389
-        self.gas = gas;
390
-        self
391
-    }
392
-
393
-    pub fn args(mut self, args: Value) -> Self {
394
-        self.args = Some(args);
395
-        self
396
-    }
397
-
398
-    #[allow(clippy::result_large_err)]
399
-    pub fn build(self) -> Result<FunctionCall<'a>> {
400
-        let action = Action::from(FunctionCallAction {
401
-            method_name: self.method_name.to_string(),
402
-            args: serialize_arguments(self.args)?,
403
-            gas: self.gas,
404
-            deposit: self.deposit,
405
-        });
406
-
407
-        Ok(FunctionCall {
408
-            info: self.info,
409
-            actions: vec![action],
410
-        })
411
-    }
412
-
413
-    /// Take a look at [`FunctionCall`] `commit`
414
-    pub async fn commit(self, block_finality: Finality) -> Result<Output> {
415
-        let call = self.build()?;
416
-        call.commit(block_finality).await
417
-    }
418
-
419
-    /// Take a look at [`FunctionCall`] `commit_async`
420
-    pub async fn commit_async(self, block_finality: Finality) -> Result<CryptoHash> {
421
-        let call = self.build()?;
422
-        call.commit_async(block_finality).await
423
-    }
424
-}
425
-
426
-pub struct FunctionCall<'a> {
427
-    info: TransactionInfo<'a>,
428
-    actions: Vec<Action>,
429
-}
430
-
431
-impl<'a> FunctionCall<'a> {
432
-    /// Sends a transaction and waits until transaction is fully complete. (Has a 10 second timeout)
433
-    /// Also, possible that an output data will be empty if the transaction is still executing
434
-    pub async fn commit(self, block_finality: Finality) -> Result<Output> {
435
-        let transaction_bytes =
436
-            serialize_transaction(&self.info, self.actions, block_finality).await?;
437
-
438
-        let execution_outcome = self
439
-            .info
440
-            .rpc()
441
-            .request(
442
-                "broadcast_tx_commit",
443
-                Some(json!(vec![base64::encode(transaction_bytes)])),
444
-            )
445
-            .await
446
-            .map_err(Error::CommitTransaction)
447
-            .and_then(|execution_outcome| {
448
-                serde_json::from_value::<FinalExecutionOutcomeView>(execution_outcome)
449
-                    .map_err(Error::DeserializeExecutionOutcome)
450
-            })?;
451
-
452
-        proceed_outcome(self.info.signer(), execution_outcome)
453
-    }
454
-
455
-    /// Sends a transaction and immediately returns transaction hash.
456
-    pub async fn commit_async(self, block_finality: Finality) -> Result<CryptoHash> {
457
-        let transaction_bytes =
458
-            serialize_transaction(&self.info, self.actions, block_finality).await?;
459
-        self.info
460
-            .rpc()
461
-            .request(
462
-                "broadcast_tx_async",
463
-                Some(json!(vec![base64::encode(transaction_bytes)])),
464
-            )
465
-            .await
466
-            .map_err(Error::CommitAsyncTransaction)
467
-            .and_then(|id| {
468
-                serde_json::from_value::<CryptoHash>(id).map_err(Error::DeserializeTransactionId)
469
-            })
470
-    }
471
-}
472
-
473
-#[allow(clippy::result_large_err)]
474
-pub(crate) fn proceed_outcome(
475
-    signer: &Signer,
476
-    execution_outcome: FinalExecutionOutcomeView,
477
-) -> Result<Output> {
478
-    signer.update_nonce(execution_outcome.transaction.nonce);
479
-    let transaction = execution_outcome.transaction_outcome;
480
-    let logs = extract_logs(execution_outcome.receipts_outcome);
481
-
482
-    match execution_outcome.status {
483
-        FinalExecutionStatus::Failure(err) => Err(Error::TxExecution(err)),
484
-        FinalExecutionStatus::SuccessValue(data) => Ok(Output {
485
-            transaction,
486
-            logs,
487
-            data,
488
-        }),
489
-        FinalExecutionStatus::NotStarted => Err(Error::TxNotStarted),
490
-        FinalExecutionStatus::Started => Ok(Output {
491
-            transaction,
492
-            logs,
493
-            data: vec![],
494
-        }),
495
-    }
496
-}

+ 0
- 51
near-rpc/src/lib.rs View File

@@ -1,51 +0,0 @@
1
-mod rpc;
2
-pub mod utils;
3
-
4
-pub mod client;
5
-pub use near_primitives_light::{self, types::Finality};
6
-
7
-type Result<T> = std::result::Result<T, Error>;
8
-
9
-#[derive(Debug, thiserror::Error)]
10
-pub enum Error {
11
-    #[error("Failed to create a signer, cause [\"{0}\"]")]
12
-    CreateSigner(common_api::crypto::Error),
13
-    #[error("Transaction not started")]
14
-    TxNotStarted,
15
-    #[error("Transaction failed during execution, cause [\"{0:?}\"]")]
16
-    TxExecution(near_primitives_light::errors::TxExecutionError),
17
-    #[error("Transaction serialization error: [\"{0}\"]")]
18
-    TxSerialization(std::io::Error),
19
-    #[error("Couldn't serialize an argument [\"{0}\"] to view a transaction, cause: [\"{1}\"]")]
20
-    SerializeTxViewArg(&'static str, serde_json::Error),
21
-    #[error("Couldn't serialize arguments for view or function call, cause: [\"{0}\"]")]
22
-    ArgsSerialization(serde_json::Error),
23
-    #[error("Client creation failed, cause: [\"{0}\"]")]
24
-    CreateClient(rpc::Error),
25
-    #[error("Can't view a transaction, cause: [\"{0}\"]")]
26
-    ViewTransaction(rpc::Error),
27
-    #[error("Transaction commit failed with an error, cause: [\"{0}\"]")]
28
-    CommitTransaction(rpc::Error),
29
-    #[error("Transaction async commit failed with an error, cause: [\"{0}\"]")]
30
-    CommitAsyncTransaction(rpc::Error),
31
-    #[error("Block call failed with an error: \"{0}\"")]
32
-    BlockCall(rpc::Error),
33
-    #[error("Access key call failed with an error: \"{0}\"")]
34
-    ViewAccessKeyCall(rpc::Error),
35
-    #[error("View call failed with an error: \"{0}\"")]
36
-    ViewCall(rpc::Error),
37
-    #[error("Couldn't deserialize a transaction function output, cause: [\"{0}\"]")]
38
-    DeserializeTransactionOutput(serde_json::Error),
39
-    #[error("Couldn't deserialize a transaction outcome, cause: [\"{0}\"]")]
40
-    DeserializeExecutionOutcome(serde_json::Error),
41
-    #[error("Couldn't deserialize a transaction id, cause: [\"{0}\"]")]
42
-    DeserializeTransactionId(serde_json::Error),
43
-    #[error("Couldn't deserialize a view call result, cause [\"{0}\"]")]
44
-    DeserializeViewCall(serde_json::Error),
45
-    #[error("Couldn't deserialize a view response, cause [\"{0}\"]")]
46
-    DeserializeResponseView(serde_json::Error),
47
-    #[error("Couldn't deserialize a block, cause: [\"{0}\"]")]
48
-    DeserializeBlock(serde_json::Error),
49
-    #[error("Can't deserialize an access key response, cause: [\"{0}\"]")]
50
-    DeserializeAccessKeyViewCall(serde_json::Error),
51
-}

+ 0
- 150
near-rpc/src/rpc/client.rs View File

@@ -1,150 +0,0 @@
1
-use reqwest::{
2
-    header::{HeaderMap, HeaderValue, CONTENT_TYPE},
3
-    Client, ClientBuilder, Response as Resp,
4
-};
5
-use serde::{Deserialize, Serialize};
6
-use serde_json::Value;
7
-
8
-use super::{Error, NearError};
9
-use std::borrow::Cow;
10
-use url::Url;
11
-
12
-type Result<T> = std::result::Result<T, Error>;
13
-
14
-pub(crate) struct RpcClient {
15
-    client: Client,
16
-    url: Url,
17
-}
18
-
19
-impl RpcClient {
20
-    /// Creates a [`reqwest`] client with headers:
21
-    /// [`CONTENT_TYPE`]: "application/json"
22
-    ///
23
-    /// Arguments
24
-    ///
25
-    /// - url - It's an RPC endpoint [`Url`]
26
-    pub(crate) fn new(url: Url) -> Result<Self> {
27
-        let mut headers = HeaderMap::new();
28
-        headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
29
-        let client = ClientBuilder::new()
30
-            .default_headers(headers)
31
-            .build()
32
-            .map_err(Error::RpcClientCreate)?;
33
-
34
-        Ok(Self { client, url })
35
-    }
36
-
37
-    /// RPC call to the NEAR network
38
-    ///
39
-    /// Arguments
40
-    ///
41
-    /// - method - RPC method
42
-    /// - params - method arguments, could be empty
43
-    ///
44
-    /// Response example:
45
-    /// ```json
46
-    /// {
47
-    ///   "id": "dontcare",
48
-    ///   "jsonrpc": "2.0",
49
-    ///   "result": "...",
50
-    /// }
51
-    ///
52
-    /// ```
53
-    pub(crate) async fn request(&self, method: &str, params: Option<Value>) -> Result<Value> {
54
-        let resp = self
55
-            .client
56
-            .post(self.url.clone())
57
-            .json(
58
-                &serde_json::to_value(&Request::new(method, params))
59
-                    .map_err(Error::SerializeRpcRequest)?,
60
-            )
61
-            .send()
62
-            .await
63
-            .and_then(Resp::error_for_status)
64
-            .map_err(Error::RpcRequest)?;
65
-
66
-        match resp
67
-            .json::<Response>()
68
-            .await
69
-            .map_err(Error::DeserializeRpcResponse)?
70
-        {
71
-            Response {
72
-                result: RpcResult::Ok(data),
73
-                ..
74
-            } => Ok(data),
75
-            Response {
76
-                result: RpcResult::Err(err),
77
-                ..
78
-            } => Err(err.into()),
79
-        }
80
-    }
81
-}
82
-
83
-#[derive(Debug, Serialize, Deserialize)]
84
-struct Request<'a> {
85
-    /// JSON-RPC version.
86
-    pub jsonrpc: &'static str,
87
-    /// Request ID
88
-    pub id: &'static str,
89
-    /// Name of the method to be invoked.
90
-    #[serde(borrow)]
91
-    pub method: Cow<'a, str>,
92
-    /// Parameter values of the request.
93
-    pub params: Option<Value>,
94
-}
95
-
96
-impl<'a> Request<'a> {
97
-    fn new(method: &'a str, params: Option<Value>) -> Self {
98
-        Self {
99
-            jsonrpc: "2.0",
100
-            id: "dontcare",
101
-            method: Cow::from(method),
102
-            params,
103
-        }
104
-    }
105
-}
106
-
107
-#[derive(Debug, Serialize, Deserialize)]
108
-struct Response {
109
-    /// JSON-RPC version.
110
-    pub jsonrpc: String,
111
-    /// Result.
112
-    #[serde(flatten)]
113
-    pub result: RpcResult,
114
-    /// Request ID
115
-    pub id: String,
116
-}
117
-
118
-/// Near result format
119
-#[derive(Debug, Serialize, Deserialize)]
120
-enum RpcResult {
121
-    #[serde(rename = "result")]
122
-    Ok(Value),
123
-    #[serde(rename = "error")]
124
-    Err(NearError),
125
-}
126
-
127
-#[cfg(test)]
128
-mod tests {
129
-
130
-    use super::*;
131
-
132
-    #[test]
133
-    fn response_sample() {
134
-        let resp = Response {
135
-            jsonrpc: "2.0".to_owned(),
136
-            result: RpcResult::Ok(Value::String("some value".to_owned())),
137
-            id: "dontcare".to_owned(),
138
-        };
139
-
140
-        assert_eq!(
141
-            serde_json::to_value(&resp).unwrap(),
142
-            serde_json::to_value(&serde_json::json!({
143
-                "id": "dontcare",
144
-                "jsonrpc": "2.0",
145
-                "result": "some value",
146
-            }))
147
-            .unwrap()
148
-        );
149
-    }
150
-}

+ 0
- 78
near-rpc/src/rpc/mod.rs View File

@@ -1,78 +0,0 @@
1
-pub(crate) mod client;
2
-
3
-use std::fmt::Display;
4
-
5
-use serde::{Deserialize, Serialize};
6
-use serde_json::Value;
7
-
8
-#[derive(Debug, thiserror::Error)]
9
-pub enum Error {
10
-    #[error("Couldn't create a RpcClient: [\"{0}\"]")]
11
-    RpcClientCreate(reqwest::Error),
12
-    #[error("Rpc request failed with: [\"{0}\"]")]
13
-    RpcRequest(reqwest::Error),
14
-    #[error("Failed to serialize an RPC request: [\"{0}\"]")]
15
-    SerializeRpcRequest(serde_json::Error),
16
-    #[error("Failed to deserialize an RPC response: [\"{0}\"]")]
17
-    DeserializeRpcResponse(reqwest::Error),
18
-    #[error("Near protocol error: [\"{0}\"]")]
19
-    NearProtocol(NearError),
20
-}
21
-
22
-impl From<NearError> for Error {
23
-    fn from(err: NearError) -> Self {
24
-        Self::NearProtocol(err)
25
-    }
26
-}
27
-
28
-#[derive(Debug, Default, Serialize, Deserialize)]
29
-pub struct NearError {
30
-    name: String,
31
-    cause: Cause,
32
-    code: i32,
33
-    data: Value,
34
-    message: String,
35
-}
36
-
37
-impl NearError {
38
-    pub fn new_simple(cause: Value) -> Self {
39
-        Self {
40
-            data: cause,
41
-            ..Default::default()
42
-        }
43
-    }
44
-
45
-    pub fn new_with_msg(cause: Value, message: String) -> Self {
46
-        Self {
47
-            data: cause,
48
-            message,
49
-            ..Default::default()
50
-        }
51
-    }
52
-}
53
-
54
-impl Display for NearError {
55
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56
-        write!(
57
-            f,
58
-            "Name: {}, Message: {}, Cause: {}, Descr: {}",
59
-            self.name, self.message, self.cause, self.data
60
-        )
61
-    }
62
-}
63
-
64
-#[derive(Debug, Default, Serialize, Deserialize)]
65
-pub struct Cause {
66
-    info: Option<Value>,
67
-    name: String,
68
-}
69
-
70
-impl Display for Cause {
71
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72
-        if let Some(info) = &self.info {
73
-            return write!(f, "{info}");
74
-        }
75
-
76
-        Ok(())
77
-    }
78
-}

+ 0
- 230
near-rpc/src/utils.rs View File

@@ -1,230 +0,0 @@
1
-use crate::{
2
-    client::{NearClient, Signer},
3
-    rpc::client::RpcClient,
4
-    Error, Result,
5
-};
6
-
7
-use near_primitives_core::{
8
-    account::id::AccountId,
9
-    hash::CryptoHash,
10
-    types::{BlockHeight, Nonce},
11
-};
12
-use near_primitives_light::{
13
-    transaction::{Action, SignedTransaction, Transaction},
14
-    types::Finality,
15
-    views::{AccessKeyPermissionView, AccessKeyView, ExecutionOutcomeWithIdView},
16
-};
17
-use serde::{
18
-    de::{self, Visitor},
19
-    Deserialize, Serialize,
20
-};
21
-use serde_json::Value;
22
-use std::fmt;
23
-
24
-#[derive(Debug, Clone, Serialize, Deserialize)]
25
-pub enum CallResult {
26
-    #[serde(rename = "result")]
27
-    Ok(Vec<u8>),
28
-    #[serde(rename = "error")]
29
-    Err(Value),
30
-}
31
-
32
-#[derive(Debug, Clone, Serialize, Deserialize)]
33
-pub struct ViewResult {
34
-    #[serde(flatten)]
35
-    pub result: CallResult,
36
-    pub logs: Vec<String>,
37
-}
38
-
39
-#[derive(Debug, Clone)]
40
-pub enum ViewAccessKeyResult {
41
-    Ok(AccessKeyView),
42
-    Err { error: String, logs: Vec<String> },
43
-}
44
-
45
-#[derive(Debug, Clone)]
46
-pub struct ViewAccessKey {
47
-    pub block_hash: CryptoHash,
48
-    pub block_height: BlockHeight,
49
-    pub result: ViewAccessKeyResult,
50
-}
51
-
52
-impl From<ViewAccessKey> for std::result::Result<Nonce, String> {
53
-    fn from(view: ViewAccessKey) -> Self {
54
-        match view.result {
55
-            ViewAccessKeyResult::Ok(AccessKeyView { nonce, .. }) => Ok(nonce),
56
-            ViewAccessKeyResult::Err { error, .. } => Err(error),
57
-        }
58
-    }
59
-}
60
-
61
-pub(crate) struct TransactionInfo<'a> {
62
-    client: &'a NearClient,
63
-    signer: &'a Signer,
64
-    contract_id: &'a AccountId,
65
-}
66
-
67
-impl<'a> TransactionInfo<'a> {
68
-    pub(crate) fn new(
69
-        client: &'a NearClient,
70
-        signer: &'a Signer,
71
-        contract_id: &'a AccountId,
72
-    ) -> Self {
73
-        Self {
74
-            client,
75
-            signer,
76
-            contract_id,
77
-        }
78
-    }
79
-
80
-    pub(crate) fn rpc(&self) -> &RpcClient {
81
-        &self.client.rpc_client
82
-    }
83
-
84
-    pub(crate) fn signer(&self) -> &Signer {
85
-        self.signer
86
-    }
87
-}
88
-
89
-pub(crate) fn extract_logs(
90
-    logs: impl IntoIterator<Item = ExecutionOutcomeWithIdView>,
91
-) -> Vec<String> {
92
-    logs.into_iter()
93
-        .find_map(|it| {
94
-            if it.outcome.logs.is_empty() {
95
-                None
96
-            } else {
97
-                Some(it.outcome.logs)
98
-            }
99
-        })
100
-        .unwrap_or_default()
101
-}
102
-
103
-/// Serialize and sign a transaction
104
-/// During call it requests the most recent block [`CryptoHash`]
105
-pub(crate) async fn serialize_transaction<'a>(
106
-    info: &'a TransactionInfo<'_>,
107
-    actions: Vec<Action>,
108
-    block_finality: Finality,
109
-) -> Result<Vec<u8>> {
110
-    let block_hash = info.client.block(block_finality).await?;
111
-
112
-    let transaction = Transaction {
113
-        signer_id: info.signer.account().clone(),
114
-        public_key: *info.signer.public_key(),
115
-        nonce: info.signer.nonce() + 1,
116
-        receiver_id: info.contract_id.clone(),
117
-        block_hash,
118
-        actions,
119
-    };
120
-
121
-    let signed_transaction = sign_transaction(info.signer, transaction);
122
-    borsh::to_vec(&signed_transaction).map_err(Error::TxSerialization)
123
-}
124
-
125
-#[allow(clippy::result_large_err)]
126
-pub(crate) fn serialize_arguments(args: Option<Value>) -> Result<Vec<u8>> {
127
-    Ok(args
128
-        .as_ref()
129
-        .map(serde_json::to_vec)
130
-        .transpose()
131
-        .map_err(Error::ArgsSerialization)?
132
-        .unwrap_or_default())
133
-}
134
-
135
-pub(crate) fn sign_transaction(signer: &Signer, transaction: Transaction) -> SignedTransaction {
136
-    let (hash, ..) = transaction.get_hash_and_size();
137
-    let signature = signer.sign(hash.0.as_ref());
138
-    SignedTransaction::new(signature, transaction)
139
-}
140
-
141
-impl<'de> Deserialize<'de> for ViewAccessKey {
142
-    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
143
-    where
144
-        D: serde::Deserializer<'de>,
145
-    {
146
-        struct Visit;
147
-
148
-        impl<'de> Visitor<'de> for Visit {
149
-            type Value = ViewAccessKey;
150
-
151
-            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
152
-                write!(formatter, "Expecting an key-value map")
153
-            }
154
-
155
-            fn visit_map<A>(self, mut map: A) -> std::result::Result<Self::Value, A::Error>
156
-            where
157
-                A: serde::de::MapAccess<'de>,
158
-            {
159
-                let block_hash = map
160
-                    .next_entry::<String, CryptoHash>()?
161
-                    .ok_or_else(|| de::Error::missing_field("block_hash"))
162
-                    .and_then(|(key, block_hash)| {
163
-                        if key != "block_hash" {
164
-                            Err(serde::de::Error::unknown_field(&key, &["block_hash"]))
165
-                        } else {
166
-                            Ok(block_hash)
167
-                        }
168
-                    })?;
169
-
170
-                let block_height = map
171
-                    .next_entry::<String, BlockHeight>()?
172
-                    .ok_or_else(|| de::Error::missing_field("block_height"))
173
-                    .and_then(|(key, block_hash)| {
174
-                        if key != "block_height" {
175
-                            Err(serde::de::Error::unknown_field(&key, &["block_height"]))
176
-                        } else {
177
-                            Ok(block_hash)
178
-                        }
179
-                    })?;
180
-
181
-                let next_key = map.next_key::<String>()?;
182
-
183
-                match next_key.as_deref() {
184
-                    Some("nonce") => {
185
-                        let nonce = map.next_value::<Nonce>()?;
186
-                        let permission = map
187
-                            .next_entry::<String, AccessKeyPermissionView>()?
188
-                            .ok_or_else(|| de::Error::missing_field("permission"))
189
-                            .and_then(|(key, permission)| {
190
-                                if key != "permission" {
191
-                                    Err(serde::de::Error::unknown_field(&key, &["permission"]))
192
-                                } else {
193
-                                    Ok(permission)
194
-                                }
195
-                            })?;
196
-
197
-                        Ok(ViewAccessKey {
198
-                            block_hash,
199
-                            block_height,
200
-                            result: ViewAccessKeyResult::Ok(AccessKeyView { nonce, permission }),
201
-                        })
202
-                    }
203
-                    Some("error") => {
204
-                        let error = map.next_value::<String>()?;
205
-                        let logs = map
206
-                            .next_entry::<String, Vec<String>>()?
207
-                            .ok_or_else(|| serde::de::Error::missing_field("logs"))
208
-                            .and_then(|(key, logs)| {
209
-                                if key != "logs" {
210
-                                    Err(serde::de::Error::unknown_field(&key, &["logs"]))
211
-                                } else {
212
-                                    Ok(logs)
213
-                                }
214
-                            })?;
215
-
216
-                        Ok(ViewAccessKey {
217
-                            block_hash,
218
-                            block_height,
219
-                            result: ViewAccessKeyResult::Err { error, logs },
220
-                        })
221
-                    }
222
-                    Some(field) => Err(serde::de::Error::unknown_field(field, &["nonce", "error"])),
223
-                    None => Err(serde::de::Error::missing_field("nonce or error")),
224
-                }
225
-            }
226
-        }
227
-
228
-        deserializer.deserialize_map(Visit)
229
-    }
230
-}

+ 0
- 458
near-rpc/tests/rpc.rs View File

@@ -1,458 +0,0 @@
1
-use near_rpc::{
2
-    client::{NearClient, Signer},
3
-    utils::{ViewAccessKey, ViewAccessKeyResult},
4
-};
5
-
6
-use std::{
7
-    fs::{create_dir_all, write},
8
-    str::FromStr,
9
-};
10
-
11
-use common_api::crypto::prelude::*;
12
-use near_primitives_light::{types::Finality, views::AccessKeyView};
13
-use rand::{RngCore, SeedableRng};
14
-use rand_chacha::ChaChaRng;
15
-use reqwest::Url;
16
-use serde_json::json;
17
-use workspaces::{network::Sandbox, types::SecretKey, AccountId, Worker};
18
-
19
-// auxiliary structs and methods
20
-fn near_client(worker: &Worker<Sandbox>) -> NearClient {
21
-    let rpc_url = Url::parse(format!("http://localhost:{}", worker.rpc_port()).as_str()).unwrap();
22
-    NearClient::new(rpc_url).unwrap()
23
-}
24
-
25
-async fn create_signer(
26
-    worker: &Worker<Sandbox>,
27
-    client: &NearClient,
28
-    signer_acc_id: &AccountId,
29
-) -> Signer {
30
-    let sk = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
31
-    let pk = Ed25519PublicKey::from(&sk);
32
-    let keypair = Keypair::new(sk).to_string();
33
-    let workspaces_sk = SecretKey::from_str(&keypair).unwrap();
34
-    let _ = worker
35
-        .create_tla(signer_acc_id.clone(), workspaces_sk)
36
-        .await
37
-        .unwrap();
38
-
39
-    let view_access_key = client
40
-        .view_access_key(signer_acc_id, &pk, Finality::None)
41
-        .await
42
-        .unwrap();
43
-
44
-    match view_access_key.result {
45
-        ViewAccessKeyResult::Ok(AccessKeyView { nonce, .. }) => {
46
-            Signer::from_secret_str(&keypair, signer_acc_id.clone(), nonce).unwrap()
47
-        }
48
-        ViewAccessKeyResult::Err { error, .. } => panic!("{error}"),
49
-    }
50
-}
51
-
52
-async fn download_contract() -> Vec<u8> {
53
-    let target = "https://github.com/near-examples/FT/raw/master/res/fungible_token.wasm";
54
-    let target_path = temp_dir().into_path();
55
-    let fname = "contract.wasm";
56
-    let full_dest = format!("{}/{}", target_path.to_string_lossy(), fname);
57
-
58
-    let contract_bytes = reqwest::get(target).await.unwrap().bytes().await.unwrap();
59
-    write(full_dest, &contract_bytes).unwrap();
60
-    contract_bytes.to_vec()
61
-}
62
-
63
-async fn clone_and_compile_wasm() -> Vec<u8> {
64
-    let tmp_path = temp_dir().into_path();
65
-    let repo_path = format!("{}/near-smartcontracts", tmp_path.to_string_lossy());
66
-    let target_path = format!("{repo_path}/test-contract");
67
-
68
-    create_dir_all(repo_path.clone()).unwrap();
69
-
70
-    let status = std::process::Command::new("git")
71
-        .arg("clone")
72
-        .arg("git@github.com:Relayz-io/near-smartcontracts.git")
73
-        .arg(&repo_path)
74
-        .spawn()
75
-        .unwrap()
76
-        .wait()
77
-        .unwrap();
78
-
79
-    if !status.success() {
80
-        panic!("Failed to clone a near-smartcontracts");
81
-    }
82
-
83
-    workspaces::compile_project(target_path.as_str())
84
-        .await
85
-        .unwrap()
86
-}
87
-
88
-fn random_bits() -> [u8; ED25519_SECRET_KEY_LENGTH] {
89
-    let mut chacha = ChaChaRng::from_entropy();
90
-    let mut secret_bytes = [0_u8; ED25519_SECRET_KEY_LENGTH];
91
-    chacha.fill_bytes(&mut secret_bytes);
92
-    secret_bytes
93
-}
94
-
95
-// tests themselves
96
-#[tokio::test]
97
-async fn contract_creation() {
98
-    let worker = workspaces::sandbox().await.unwrap();
99
-    let client = near_client(&worker);
100
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
101
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
102
-    let wasm = download_contract().await;
103
-
104
-    client
105
-        .deploy_contract(&signer, &signer_account_id, wasm)
106
-        .commit(Finality::None)
107
-        .await
108
-        .unwrap();
109
-}
110
-
111
-#[tokio::test]
112
-async fn contract_function_call() {
113
-    let worker = workspaces::sandbox().await.unwrap();
114
-    let client = near_client(&worker);
115
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
116
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
117
-    let wasm = download_contract().await;
118
-
119
-    client
120
-        .deploy_contract(&signer, &signer_account_id, wasm)
121
-        .commit(Finality::None)
122
-        .await
123
-        .unwrap();
124
-
125
-    client
126
-        .function_call(&signer, &signer_account_id, "new_default_meta")
127
-        .args(json!({
128
-            "owner_id": &signer_account_id,
129
-            "total_supply": "100",
130
-        }))
131
-        .gas(near_units::parse_gas!("300 T") as u64)
132
-        .commit(Finality::None)
133
-        .await
134
-        .unwrap();
135
-}
136
-
137
-#[tokio::test]
138
-async fn contract_function_call_failed() {
139
-    let worker = workspaces::sandbox().await.unwrap();
140
-    let client = near_client(&worker);
141
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
142
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
143
-    let wasm = download_contract().await;
144
-
145
-    client
146
-        .deploy_contract(&signer, &signer_account_id, wasm)
147
-        .commit(Finality::None)
148
-        .await
149
-        .unwrap();
150
-
151
-    assert!(client
152
-        .function_call(&signer, &signer_account_id, "new_default_meta")
153
-        .args(json!({
154
-            "owner_id": &signer_account_id,
155
-            "total_suppl": "100",
156
-        }))
157
-        .gas(near_units::parse_gas!("300 T") as u64)
158
-        .commit(Finality::None)
159
-        .await
160
-        .is_err());
161
-
162
-    client
163
-        .function_call(&signer, &signer_account_id, "new_default_meta")
164
-        .args(json!({
165
-            "owner_id": &signer_account_id,
166
-            "total_supply": "100",
167
-        }))
168
-        .gas(near_units::parse_gas!("300 T") as u64)
169
-        .commit(Finality::None)
170
-        .await
171
-        .unwrap();
172
-}
173
-
174
-#[tokio::test]
175
-async fn multiple_tests() {
176
-    let worker = workspaces::sandbox().await.unwrap();
177
-    let client = near_client(&worker);
178
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
179
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
180
-
181
-    let wasm = clone_and_compile_wasm().await;
182
-
183
-    init_contract(&client, &signer_account_id, &signer, wasm).await;
184
-    fc_no_params(&client, &signer_account_id, &signer).await;
185
-    fc_with_one_param_and_result(&client, &signer_account_id, &signer).await;
186
-    fc_with_param_and_result(&client, &signer_account_id, &signer).await;
187
-    view_no_params(&client, &signer_account_id).await;
188
-    view_with_params(&client, &signer_account_id).await;
189
-}
190
-
191
-async fn init_contract(
192
-    client: &NearClient,
193
-    contract_id: &AccountId,
194
-    signer: &Signer,
195
-    wasm: Vec<u8>,
196
-) {
197
-    client
198
-        .deploy_contract(signer, contract_id, wasm)
199
-        .commit(Finality::None)
200
-        .await
201
-        .unwrap();
202
-}
203
-
204
-async fn view_no_params(client: &NearClient, contract_id: &AccountId) {
205
-    client
206
-        .view::<u64>(contract_id, Finality::None, "show_id", None)
207
-        .await
208
-        .unwrap();
209
-}
210
-
211
-async fn view_with_params(client: &NearClient, contract_id: &AccountId) {
212
-    client
213
-        .view::<String>(
214
-            contract_id,
215
-            Finality::None,
216
-            "show_type",
217
-            Some(json!({"is_message": true})),
218
-        )
219
-        .await
220
-        .unwrap();
221
-}
222
-
223
-// fc = function call
224
-async fn fc_no_params(client: &NearClient, contract_id: &AccountId, signer: &Signer) {
225
-    client
226
-        .function_call(signer, contract_id, "increment")
227
-        .gas(near_units::parse_gas!("300 T") as u64)
228
-        .commit(Finality::None)
229
-        .await
230
-        .unwrap();
231
-}
232
-
233
-async fn fc_with_one_param_and_result(
234
-    client: &NearClient,
235
-    contract_id: &AccountId,
236
-    signer: &Signer,
237
-) {
238
-    let expected_result = "change message";
239
-    let message = client
240
-        .function_call(signer, contract_id, "change_message")
241
-        .args(json!({ "message": expected_result }))
242
-        .gas(near_units::parse_gas!("300 T") as u64)
243
-        .commit(Finality::Final)
244
-        .await
245
-        .unwrap()
246
-        .output::<String>()
247
-        .unwrap();
248
-
249
-    assert_eq!(message, expected_result);
250
-}
251
-
252
-async fn fc_with_param_and_result(client: &NearClient, contract_id: &AccountId, signer: &Signer) {
253
-    let expected_id = 666u64;
254
-    let id = client
255
-        .function_call(signer, contract_id, "change_id")
256
-        .args(json!({ "id": expected_id }))
257
-        .gas(near_units::parse_gas!("300 T") as u64)
258
-        .commit(Finality::Final)
259
-        .await
260
-        .unwrap()
261
-        .output::<u64>()
262
-        .unwrap();
263
-
264
-    assert_eq!(id, expected_id);
265
-}
266
-
267
-#[tokio::test]
268
-async fn async_transaction() {
269
-    let worker = workspaces::sandbox().await.unwrap();
270
-    let client = near_client(&worker);
271
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
272
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
273
-
274
-    let wasm = clone_and_compile_wasm().await;
275
-
276
-    client
277
-        .deploy_contract(&signer, &signer_account_id, wasm)
278
-        .commit(Finality::None)
279
-        .await
280
-        .unwrap();
281
-
282
-    let expected_result = "change message";
283
-    let transaction_id = client
284
-        .function_call(&signer, &signer_account_id, "change_message")
285
-        .args(json!({ "message": expected_result }))
286
-        .gas(near_units::parse_gas!("300 T") as u64)
287
-        .commit_async(Finality::Final)
288
-        .await
289
-        .unwrap();
290
-
291
-    let (tx, rx) = tokio::sync::oneshot::channel::<()>();
292
-
293
-    tokio::spawn(async move {
294
-        tokio::time::timeout(std::time::Duration::from_secs(3), rx)
295
-            .await
296
-            .expect("Wait async transaction timeout")
297
-    });
298
-
299
-    loop {
300
-        let res = client.view_transaction(&transaction_id, &signer).await;
301
-
302
-        if let Err(near_rpc::Error::ViewTransaction(_)) = &res {
303
-            // try one more time
304
-            continue;
305
-        }
306
-
307
-        // cancel timeout
308
-        tx.send(()).unwrap();
309
-        let msg = res.unwrap().output::<String>().unwrap();
310
-
311
-        assert_eq!(msg, expected_result);
312
-        break;
313
-    }
314
-}
315
-
316
-#[tokio::test]
317
-async fn view_access_key_success() {
318
-    let worker = workspaces::sandbox().await.unwrap();
319
-    let client = near_client(&worker);
320
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
321
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
322
-
323
-    let new_acc = AccountId::from_str("one.alice.test.near").unwrap();
324
-    let secret_key = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
325
-    let pk = Ed25519PublicKey::from(&secret_key);
326
-
327
-    let _ = client
328
-        .create_account(&signer, &new_acc, pk, near_units::parse_near!("3 N"))
329
-        .commit(Finality::None)
330
-        .await
331
-        .unwrap()
332
-        .output::<serde_json::Value>();
333
-
334
-    let access_key = client
335
-        .view_access_key(&new_acc, &pk, Finality::None)
336
-        .await
337
-        .unwrap();
338
-    assert!(matches!(
339
-        access_key,
340
-        ViewAccessKey {
341
-            result: ViewAccessKeyResult::Ok { .. },
342
-            ..
343
-        }
344
-    ));
345
-}
346
-
347
-#[tokio::test]
348
-async fn view_access_key_failure() {
349
-    let worker = workspaces::sandbox().await.unwrap();
350
-    let client = near_client(&worker);
351
-
352
-    let new_acc = AccountId::from_str("one.alice.test.near").unwrap();
353
-    let secret_key = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
354
-    let pk = Ed25519PublicKey::from(&secret_key);
355
-
356
-    let access_key = client
357
-        .view_access_key(&new_acc, &pk, Finality::None)
358
-        .await
359
-        .unwrap();
360
-    assert!(matches!(
361
-        access_key,
362
-        ViewAccessKey {
363
-            result: ViewAccessKeyResult::Err { .. },
364
-            ..
365
-        }
366
-    ));
367
-}
368
-
369
-#[tokio::test]
370
-async fn create_account() {
371
-    let worker = workspaces::sandbox().await.unwrap();
372
-    let client = near_client(&worker);
373
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
374
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
375
-
376
-    let new_acc = AccountId::from_str("one.alice.test.near").unwrap();
377
-    let secret_key = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
378
-    let pk = Ed25519PublicKey::from(&secret_key);
379
-
380
-    let _ = client
381
-        .create_account(&signer, &new_acc, pk, near_units::parse_near!("3 N"))
382
-        .commit(Finality::Final)
383
-        .await
384
-        .unwrap()
385
-        .output::<serde_json::Value>();
386
-
387
-    let access_key = client
388
-        .view_access_key(&new_acc, &pk, Finality::None)
389
-        .await
390
-        .unwrap();
391
-    assert!(matches!(
392
-        access_key,
393
-        ViewAccessKey {
394
-            result: ViewAccessKeyResult::Ok { .. },
395
-            ..
396
-        }
397
-    ));
398
-}
399
-
400
-#[tokio::test]
401
-async fn delete_account() {
402
-    let worker = workspaces::sandbox().await.unwrap();
403
-    let client = near_client(&worker);
404
-    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
405
-    let signer = create_signer(&worker, &client, &signer_account_id).await;
406
-
407
-    let new_acc = AccountId::from_str("one.alice.test.near").unwrap();
408
-    let secret_key = Ed25519SecretKey::try_from_bytes(&random_bits()).unwrap();
409
-    let pk = Ed25519PublicKey::from(&secret_key);
410
-
411
-    client
412
-        .create_account(&signer, &new_acc, pk, near_units::parse_near!("3 N"))
413
-        .commit(Finality::Final)
414
-        .await
415
-        .unwrap();
416
-
417
-    let access_key = client
418
-        .view_access_key(&new_acc, &pk, Finality::None)
419
-        .await
420
-        .unwrap();
421
-
422
-    let nonce = if let ViewAccessKey {
423
-        result: ViewAccessKeyResult::Ok(AccessKeyView { nonce, .. }),
424
-        ..
425
-    } = access_key
426
-    {
427
-        nonce
428
-    } else {
429
-        panic!("Can't view access key for just created account")
430
-    };
431
-
432
-    let acc_signer = Signer::from_secret(secret_key, new_acc.clone(), nonce);
433
-
434
-    client
435
-        .delete_account(&acc_signer, &new_acc, &signer_account_id)
436
-        .commit(Finality::Final)
437
-        .await
438
-        .unwrap();
439
-
440
-    let access_key = client
441
-        .view_access_key(&new_acc, &pk, Finality::None)
442
-        .await
443
-        .unwrap();
444
-    assert!(matches!(
445
-        access_key,
446
-        ViewAccessKey {
447
-            result: ViewAccessKeyResult::Err { .. },
448
-            ..
449
-        }
450
-    ));
451
-}
452
-
453
-fn temp_dir() -> tempfile::TempDir {
454
-    tempfile::Builder::new()
455
-        .prefix("near-client-test-")
456
-        .tempdir()
457
-        .unwrap()
458
-}

+ 1
- 2
web-client/Cargo.toml View File

@@ -21,10 +21,9 @@ gloo-timers = { version = "0.2", features = ["futures-core", "futures"] }
21 21
 itertools = "0.10"
22 22
 js-sys = "0.3"
23 23
 log = "0.4"
24
-near-primitives-light = { path = "../near-primitives-light" }
24
+near-client = "0.1"
25 25
 near-primitives-core = "0.15"
26 26
 near-units = "0.2"
27
-near-rpc = { path = "../near-rpc" }
28 27
 rand = { version = "0.8" }
29 28
 rand_chacha = "0.3"
30 29
 reqwest = { version = "0.11", features = ["json"] }

+ 1
- 6
web-client/src/contract.rs View File

@@ -1,10 +1,5 @@
1
-use near_rpc::{
2
-    client::{NearClient, Signer},
3
-    Finality,
4
-};
5
-
6 1
 use crate::{error::ApiError, Handler};
7
-use common_api::crypto::prelude::*;
2
+use near_client::{crypto::prelude::*, prelude::*, Finality};
8 3
 use near_primitives_core::{hash::CryptoHash, types::AccountId};
9 4
 use near_units::parse_gas;
10 5
 use std::collections::HashSet;

+ 1
- 1
web-client/src/crypto.rs View File

@@ -1,6 +1,6 @@
1 1
 use crate::error::ApiError;
2 2
 use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit, Nonce};
3
-use common_api::{crypto::prelude::*, crypto::Error};
3
+use near_client::{crypto::prelude::*, crypto::Error};
4 4
 use rand::{RngCore, SeedableRng};
5 5
 use rand_chacha::ChaChaRng;
6 6
 use uuid::Uuid;

+ 1
- 2
web-client/src/error.rs View File

@@ -1,6 +1,5 @@
1
-use common_api::crypto::Error as CryptoErr;
1
+use near_client::{crypto::Error as CryptoErr, Error};
2 2
 use near_primitives_core::account::id::ParseAccountError;
3
-use near_rpc::Error;
4 3
 use reqwest::Error as ExchangeError;
5 4
 use serde::{Deserialize, Serialize};
6 5
 use serde_json::Error as SerializationError;

+ 1
- 1
web-client/src/exchange_client.rs View File

@@ -9,8 +9,8 @@ use reqwest::{
9 9
 };
10 10
 
11 11
 use crate::{contract::view_server_key, error::ApiError, Handler};
12
+use near_client::prelude::*;
12 13
 use near_primitives_core::types::AccountId;
13
-use near_rpc::client::Signer;
14 14
 use std::{collections::HashSet, time::Duration};
15 15
 use uuid::Uuid;
16 16
 use wasm_bindgen::JsValue;

+ 1
- 1
web-client/src/lib.rs View File

@@ -17,8 +17,8 @@ use gloo_timers::future::TimeoutFuture;
17 17
 use itertools::Itertools;
18 18
 use js_sys::Promise;
19 19
 use log::{info, warn};
20
+use near_client::prelude::*;
20 21
 use near_primitives_core::{account::id::AccountId, hash::CryptoHash, types::Nonce};
21
-use near_rpc::client::Signer;
22 22
 use serde::{Deserialize, Serialize};
23 23
 use std::{collections::HashSet, str::FromStr, sync::Arc};
24 24
 use url::Url;

+ 1
- 3
web-client/tests/integration.rs View File

@@ -1,7 +1,5 @@
1
-use common_api::crypto::prelude::*;
1
+use near_client::{crypto::prelude::*, prelude::*, Finality};
2 2
 use near_primitives_core::account::id::AccountId;
3
-use near_primitives_light::types::Finality;
4
-use near_rpc::client::{NearClient, Signer};
5 3
 use serde::{Deserialize, Serialize};
6 4
 use std::str::FromStr;
7 5
 use url::Url;

Loading…
Cancel
Save