@dashevo/dapi-grpc 0.25.21 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/Cargo.toml +35 -16
  2. package/build.rs +139 -56
  3. package/clients/core/v0/nodejs/CorePromiseClient.js +124 -13
  4. package/clients/core/v0/nodejs/core_pbjs.js +1922 -987
  5. package/clients/core/v0/nodejs/core_protoc.js +1291 -645
  6. package/clients/core/v0/rust/core_example.rs +1 -1
  7. package/clients/core/v0/web/CorePromiseClient.js +49 -5
  8. package/clients/core/v0/web/core_pb.d.ts +173 -89
  9. package/clients/core/v0/web/core_pb.js +1291 -645
  10. package/clients/core/v0/web/core_pb_service.d.ts +59 -10
  11. package/clients/core/v0/web/core_pb_service.js +134 -6
  12. package/clients/platform/v0/nodejs/PlatformPromiseClient.js +208 -14
  13. package/clients/platform/v0/nodejs/platform_pbjs.js +22951 -9938
  14. package/clients/platform/v0/nodejs/platform_protoc.js +22332 -9091
  15. package/clients/platform/v0/rust/platform_example.rs +1 -1
  16. package/clients/platform/v0/web/PlatformPromiseClient.js +64 -8
  17. package/clients/platform/v0/web/platform_pb.d.ts +2057 -302
  18. package/clients/platform/v0/web/platform_pb.js +22332 -9091
  19. package/clients/platform/v0/web/platform_pb_service.d.ts +187 -35
  20. package/clients/platform/v0/web/platform_pb_service.js +355 -35
  21. package/package.json +2 -2
  22. package/protos/core/v0/core.proto +45 -23
  23. package/protos/platform/v0/platform.proto +429 -50
  24. package/src/lib.rs +26 -2
  25. package/src/mock/serde_mockable.rs +105 -0
  26. package/src/mock.rs +130 -0
  27. package/test/unit/clients/core/v0/nodejs/CorePromiseClient.spec.js +27 -6
  28. package/test/unit/clients/platform/v0/nodejs/PlatformPromiseClient.spec.js +55 -1
  29. package/test/unit/getCoreDefinition.spec.js +5 -2
  30. package/src/core/proto/org.dash.platform.dapi.v0.rs +0 -666
  31. package/src/platform/proto/org.dash.platform.dapi.v0.rs +0 -2481
@@ -0,0 +1,105 @@
1
+ //! Serde serialization and deserialization for Mockable objects.
2
+ //!
3
+ //! This module provides a custom serialization and deserialization implementation for Mockable objects.
4
+ //!
5
+ //! /// ## Example
6
+ ///
7
+ /// ```rust
8
+ /// struct SomeObject {
9
+ /// field: u32,
10
+ /// }
11
+ ///
12
+ /// impl dapi_grpc::mock::Mockable for SomeObject {
13
+ /// fn mock_serialize(&self) -> Option<Vec<u8>> {
14
+ /// Some(self.field.to_be_bytes().to_vec())
15
+ /// }
16
+ ///
17
+ /// fn mock_deserialize(bytes: &[u8]) -> Option<Self> {
18
+ /// if bytes.len() != 4 {
19
+ /// return None;
20
+ /// }
21
+ ///
22
+ /// Some(SomeObject {
23
+ /// field: u32::from_be_bytes(bytes.try_into().expect("4 bytes")),
24
+ /// })
25
+ /// }
26
+ /// }
27
+ ///
28
+ /// #[derive(serde::Serialize,serde::Deserialize)]
29
+ /// struct TestStruct {
30
+ /// #[serde(with="dapi_grpc::mock::serde_mockable")]
31
+ /// field: SomeObject,
32
+ /// }
33
+ /// ```
34
+ use super::Mockable;
35
+
36
+ use serde::{
37
+ de::{self, Visitor},
38
+ Deserializer, Serializer,
39
+ };
40
+ use serde_bytes::Deserialize;
41
+ use std::fmt;
42
+ use std::marker::PhantomData;
43
+
44
+ /// Serialize any Mockable object to bytes.
45
+ ///
46
+ /// ## Example
47
+ ///
48
+ /// `#[serde(with="dapi_grpc::mock::serde_mockable")]`
49
+ pub fn serialize<T: Mockable, S>(data: &T, serializer: S) -> Result<S::Ok, S::Error>
50
+ where
51
+ S: Serializer,
52
+ {
53
+ match data.mock_serialize() {
54
+ Some(bytes) => serializer.serialize_bytes(bytes.as_slice()),
55
+ None => Err(serde::ser::Error::custom(
56
+ "Mockable object is not serializable",
57
+ )),
58
+ }
59
+ }
60
+
61
+ struct MockableVisitor<T> {
62
+ marker: PhantomData<T>,
63
+ }
64
+
65
+ impl<'de, T> Visitor<'de> for MockableVisitor<T>
66
+ where
67
+ T: Mockable,
68
+ {
69
+ type Value = T;
70
+
71
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
72
+ formatter.write_str("a byte array")
73
+ }
74
+
75
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
76
+ where
77
+ E: de::Error,
78
+ {
79
+ T::mock_deserialize(v).ok_or_else(|| E::custom("Failed to deserialize Mockable object"))
80
+ }
81
+
82
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
83
+ where
84
+ A: de::SeqAccess<'de>,
85
+ {
86
+ let bytes = <Vec<u8>>::deserialize(de::value::SeqAccessDeserializer::new(seq))?;
87
+ T::mock_deserialize(&bytes).ok_or_else(|| {
88
+ serde::de::Error::custom("Failed to deserialize Mockable object from seq")
89
+ })
90
+ }
91
+ }
92
+
93
+ /// Deserialize any Mockable object from bytes.
94
+ ///
95
+ /// ## Example
96
+ ///
97
+ /// `#[serde(with="dapi_grpc::mock::serde_mockable")]`
98
+ pub fn deserialize<'de, T: Mockable, D>(deserializer: D) -> Result<T, D::Error>
99
+ where
100
+ D: Deserializer<'de>,
101
+ {
102
+ deserializer.deserialize_bytes(MockableVisitor {
103
+ marker: PhantomData,
104
+ })
105
+ }
package/src/mock.rs ADDED
@@ -0,0 +1,130 @@
1
+ //! Mocking support for messages.
2
+ //!
3
+ //! Contains [Mockable] trait that should be implemented by any object that can be used in the DAPI.
4
+ //!
5
+ //! Note that this trait is defined even if mocks are not supported, but it should always return `None` on serialization.
6
+
7
+ #[cfg(feature = "mocks")]
8
+ pub mod serde_mockable;
9
+
10
+ use tonic::Streaming;
11
+
12
+ /// Mocking support for messages.
13
+ ///
14
+ /// This trait should be implemented by any object that can be used in the DAPI.
15
+ ///
16
+ /// We use serde_json to serialize/deserialize messages.
17
+ // TODO: Move to a different crate where it can be easily shared by dapi-grpc, dash-platform-sdk, and rs-dapi-client.
18
+ pub trait Mockable
19
+ where
20
+ Self: std::marker::Sized,
21
+ {
22
+ /// Serialize the message to bytes for mocking purposes.
23
+ ///
24
+ /// Returns None if the message is not serializable or mocking is disabled.
25
+ ///
26
+ /// # Panics
27
+ ///
28
+ /// Panics on any error.
29
+ fn mock_serialize(&self) -> Option<Vec<u8>> {
30
+ None
31
+ }
32
+ /// Deserialize the message serialized with [mock_serialize()].
33
+ ///
34
+ /// Returns None if the message is not serializable or mocking is disabled.
35
+ ///
36
+ /// # Panics
37
+ ///
38
+ /// Panics on any error.
39
+ fn mock_deserialize(_data: &[u8]) -> Option<Self> {
40
+ None
41
+ }
42
+ }
43
+ #[cfg(feature = "mocks")]
44
+ #[derive(serde::Serialize, serde::Deserialize)]
45
+ enum SerializableResult {
46
+ Ok(Vec<u8>),
47
+ Err(Vec<u8>),
48
+ }
49
+ impl<T, E> Mockable for Result<T, E>
50
+ where
51
+ T: Mockable,
52
+ E: Mockable,
53
+ {
54
+ #[cfg(feature = "mocks")]
55
+ fn mock_serialize(&self) -> Option<Vec<u8>> {
56
+ let serializable = match self {
57
+ Ok(value) => SerializableResult::Ok(value.mock_serialize()?),
58
+ Err(error) => SerializableResult::Err(error.mock_serialize()?),
59
+ };
60
+ serde_json::to_vec(&serializable).ok()
61
+ }
62
+
63
+ #[cfg(feature = "mocks")]
64
+ fn mock_deserialize(data: &[u8]) -> Option<Self> {
65
+ if data.is_empty() {
66
+ return None;
67
+ }
68
+ let deser: SerializableResult =
69
+ serde_json::from_slice(data).expect("unable to deserialize mock data");
70
+ Some(match deser {
71
+ SerializableResult::Ok(data) => Ok(T::mock_deserialize(&data)?),
72
+ SerializableResult::Err(data) => Err(E::mock_deserialize(&data)?),
73
+ })
74
+ }
75
+ }
76
+
77
+ impl<T: Mockable> Mockable for Option<T> {
78
+ #[cfg(feature = "mocks")]
79
+ fn mock_serialize(&self) -> Option<Vec<u8>> {
80
+ self.as_ref().and_then(|value| value.mock_serialize())
81
+ }
82
+
83
+ #[cfg(feature = "mocks")]
84
+ fn mock_deserialize(data: &[u8]) -> Option<Self> {
85
+ T::mock_deserialize(data).map(Some)
86
+ }
87
+ }
88
+
89
+ impl Mockable for Vec<u8> {
90
+ #[cfg(feature = "mocks")]
91
+ fn mock_serialize(&self) -> Option<Vec<u8>> {
92
+ serde_json::to_vec(self).ok()
93
+ }
94
+
95
+ #[cfg(feature = "mocks")]
96
+ fn mock_deserialize(data: &[u8]) -> Option<Self> {
97
+ serde_json::from_slice(data).ok()
98
+ }
99
+ }
100
+ #[cfg(feature = "mocks")]
101
+ #[derive(serde::Serialize, serde::Deserialize)]
102
+ struct MockableStatus {
103
+ code: i32,
104
+ message: Vec<u8>,
105
+ }
106
+ impl Mockable for crate::tonic::Status {
107
+ #[cfg(feature = "mocks")]
108
+ fn mock_serialize(&self) -> Option<Vec<u8>> {
109
+ let mockable = MockableStatus {
110
+ code: self.code().into(),
111
+ message: self.message().as_bytes().to_vec(),
112
+ };
113
+
114
+ Some(serde_json::to_vec(&mockable).expect("unable to serialize tonic::Status"))
115
+ }
116
+
117
+ #[cfg(feature = "mocks")]
118
+ fn mock_deserialize(data: &[u8]) -> Option<Self> {
119
+ let MockableStatus { code, message } =
120
+ serde_json::from_slice(data).expect("unable to deserialize tonic::Status");
121
+ let message = std::str::from_utf8(&message).expect("invalid utf8 message in tonic::Status");
122
+ Some(Self::new(code.into(), message))
123
+ }
124
+ }
125
+
126
+ /// Mocking of gRPC streaming responses is not supported.
127
+ ///
128
+ /// This will return `None` on serialization,
129
+ /// effectively disabling mocking of streaming responses.
130
+ impl<T: Mockable> Mockable for Streaming<T> {}
@@ -11,7 +11,8 @@ describe('CorePromiseClient', () => {
11
11
 
12
12
  corePromiseClient = new CorePromiseClient('https://localhost/');
13
13
  corePromiseClient.client = {
14
- getStatus: this.sinon.stub().resolves(response),
14
+ getBlockchainStatus: this.sinon.stub().resolves(response),
15
+ getMasternodeStatus: this.sinon.stub().resolves(response),
15
16
  getBlock: this.sinon.stub().resolves(response),
16
17
  broadcastTransaction: this.sinon.stub().resolves(response),
17
18
  getTransaction: this.sinon.stub().resolves(response),
@@ -20,17 +21,37 @@ describe('CorePromiseClient', () => {
20
21
  };
21
22
  });
22
23
 
23
- describe('#getStatus', () => {
24
- it('should return status', async () => {
25
- const result = await corePromiseClient.getStatus(request);
24
+ describe('#getBlockchainStatus', () => {
25
+ it('should return core chain status', async () => {
26
+ const result = await corePromiseClient.getBlockchainStatus(request);
27
+
28
+ expect(result).to.equal(response);
29
+ expect(corePromiseClient.client.getBlockchainStatus).to.be.calledOnceWith(request);
30
+ });
31
+
32
+ it('should throw an error when metadata is not an object', async () => {
33
+ try {
34
+ corePromiseClient.getBlockchainStatus({}, 'metadata');
35
+
36
+ expect.fail('Error was not thrown');
37
+ } catch (e) {
38
+ expect(e.message).to.equal('metadata must be an object');
39
+ }
40
+ });
41
+ });
42
+
43
+ describe('#getMasternodeStatus', () => {
44
+ it('should return masternode status', async () => {
45
+ const result = await corePromiseClient.getMasternodeStatus(request);
26
46
 
27
47
  expect(result).to.equal(response);
28
- expect(corePromiseClient.client.getStatus).to.be.calledOnceWith(request);
48
+ expect(corePromiseClient.client.getMasternodeStatus)
49
+ .to.be.calledOnceWith(request);
29
50
  });
30
51
 
31
52
  it('should throw an error when metadata is not an object', async () => {
32
53
  try {
33
- corePromiseClient.getStatus({}, 'metadata');
54
+ corePromiseClient.getMasternodeStatus({}, 'metadata');
34
55
 
35
56
  expect.fail('Error was not thrown');
36
57
  } catch (e) {
@@ -13,11 +13,15 @@ describe('PlatformPromiseClient', () => {
13
13
  platformPromiseClient.client = {
14
14
  broadcastStateTransition: this.sinon.stub().resolves(response),
15
15
  getIdentity: this.sinon.stub().resolves(response),
16
+ getIdentitiesContractKeys: this.sinon.stub().resolves(response),
16
17
  getDataContract: this.sinon.stub().resolves(response),
17
18
  getDocuments: this.sinon.stub().resolves(response),
18
19
  getEpochsInfo: this.sinon.stub().resolves(response),
19
20
  getProtocolVersionUpgradeVoteStatus: this.sinon.stub().resolves(response),
20
21
  getProtocolVersionUpgradeState: this.sinon.stub().resolves(response),
22
+ getIdentityContractNonce: this.sinon.stub().resolves(response),
23
+ getIdentityNonce: this.sinon.stub().resolves(response),
24
+ getIdentityKeys: this.sinon.stub().resolves(response),
21
25
  };
22
26
  });
23
27
 
@@ -60,6 +64,26 @@ describe('PlatformPromiseClient', () => {
60
64
  });
61
65
  });
62
66
 
67
+ describe('#getIdentitiesContractKeys', () => {
68
+ it('should get identities', async () => {
69
+ const result = await platformPromiseClient.getIdentitiesContractKeys(request);
70
+
71
+ expect(result).to.equal(response);
72
+ expect(platformPromiseClient.client.getIdentitiesContractKeys)
73
+ .to.be.calledOnceWith(request);
74
+ });
75
+
76
+ it('should throw an error when metadata is not an object', async () => {
77
+ try {
78
+ platformPromiseClient.getIdentitiesContractKeys({}, 'metadata');
79
+
80
+ expect.fail('Error was not thrown');
81
+ } catch (e) {
82
+ expect(e.message).to.equal('metadata must be an object');
83
+ }
84
+ });
85
+ });
86
+
63
87
  describe('#getDataContract', () => {
64
88
  it('should get data contract', async () => {
65
89
  const result = await platformPromiseClient.getDataContract(request);
@@ -98,7 +122,7 @@ describe('PlatformPromiseClient', () => {
98
122
  });
99
123
 
100
124
  describe('#getProtocolVersionUpgradeVoteStatus', () => {
101
- it('should get version upgrade vote status', async () => {
125
+ it('should get version upgrade votes status', async () => {
102
126
  const result = await platformPromiseClient.getProtocolVersionUpgradeVoteStatus(request);
103
127
 
104
128
  expect(result).to.equal(response);
@@ -116,4 +140,34 @@ describe('PlatformPromiseClient', () => {
116
140
  .to.be.calledOnceWith(request);
117
141
  });
118
142
  });
143
+
144
+ describe('#getIdentityContractNonce', () => {
145
+ it('should get identity contract nonce', async () => {
146
+ const result = await platformPromiseClient.getIdentityContractNonce(request);
147
+
148
+ expect(result).to.equal(response);
149
+ expect(platformPromiseClient.client.getIdentityContractNonce)
150
+ .to.be.calledOnceWith(request);
151
+ });
152
+ });
153
+
154
+ describe('#getIdentityNonce', () => {
155
+ it('should get identity nonce', async () => {
156
+ const result = await platformPromiseClient.getIdentityNonce(request);
157
+
158
+ expect(result).to.equal(response);
159
+ expect(platformPromiseClient.client.getIdentityNonce)
160
+ .to.be.calledOnceWith(request);
161
+ });
162
+ });
163
+
164
+ describe('#getIdentityKeys', () => {
165
+ it('should get identity keys', async () => {
166
+ const result = await platformPromiseClient.getIdentityKeys(request);
167
+
168
+ expect(result).to.equal(response);
169
+ expect(platformPromiseClient.client.getIdentityKeys)
170
+ .to.be.calledOnceWith(request);
171
+ });
172
+ });
119
173
  });
@@ -14,8 +14,11 @@ describe('getCoreDefinition', () => {
14
14
  expect(coreDefinition.service).to.have.property('getTransaction');
15
15
  expect(coreDefinition.service.getTransaction.path).to.equal('/org.dash.platform.dapi.v0.Core/getTransaction');
16
16
 
17
- expect(coreDefinition.service).to.have.property('getStatus');
18
- expect(coreDefinition.service.getStatus.path).to.equal('/org.dash.platform.dapi.v0.Core/getStatus');
17
+ expect(coreDefinition.service).to.have.property('getBlockchainStatus');
18
+ expect(coreDefinition.service.getBlockchainStatus.path).to.equal('/org.dash.platform.dapi.v0.Core/getBlockchainStatus');
19
+
20
+ expect(coreDefinition.service).to.have.property('getMasternodeStatus');
21
+ expect(coreDefinition.service.getMasternodeStatus.path).to.equal('/org.dash.platform.dapi.v0.Core/getMasternodeStatus');
19
22
 
20
23
  expect(coreDefinition.service).to.have.property('getBlock');
21
24
  expect(coreDefinition.service.getBlock.path).to.equal('/org.dash.platform.dapi.v0.Core/getBlock');