From 6966c18cca0801de3f5c8d529295e814ed0dab29 Mon Sep 17 00:00:00 2001 From: owl352 Date: Tue, 3 Sep 2024 23:55:57 +0300 Subject: [PATCH 1/7] initial commit --- .../v0/nodejs/PlatformPromiseClient.js | 24 +++---- .../methods/platform/PlatformMethodsFacade.js | 4 +- .../GetIdentityBalanceResponse.js | 43 +++++++++++ .../getIdentityBalanceFactory.js | 71 +++++++++++++++++++ 4 files changed, 128 insertions(+), 14 deletions(-) create mode 100644 packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js create mode 100644 packages/js-dapi-client/lib/methods/platform/getIdentityBalance/getIdentityBalanceFactory.js diff --git a/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js b/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js index b2a6d25bb2..4047b47aca 100644 --- a/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js +++ b/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js @@ -60,8 +60,8 @@ const { GetIdentityKeysResponse: PBJSGetIdentityKeysResponse, GetTotalCreditsInPlatformRequest: PBJSGetTotalCreditsInPlatformRequest, GetTotalCreditsInPlatformResponse: PBJSGetTotalCreditsInPlatformResponse, - GetStatusRequest: PBJSGetStatusRequest, - GetStatusResponse: PBJSGetStatusResponse, + GetIdentityBalanceRequest: PBJSGetIdentityBalanceRequest, + GetIdentityBalanceResponse: PBJSGetIdentityBalanceResponse, }, }, }, @@ -87,7 +87,7 @@ const { GetIdentityNonceResponse: ProtocGetIdentityNonceResponse, GetIdentityKeysResponse: ProtocGetIdentityKeysResponse, GetTotalCreditsInPlatformResponse: ProtocGetTotalCreditsInPlatformResponse, - GetStatusResponse: ProtocGetStatusResponse, + GetIdentityBalanceResponse: ProtocGetIdentityBalanceResponse, } = require('./platform_protoc'); const getPlatformDefinition = require('../../../../lib/getPlatformDefinition'); @@ -182,8 +182,8 @@ class PlatformPromiseClient { this.client.getTotalCreditsInPlatform.bind(this.client), ); - this.client.getStatus = promisify( - this.client.getStatus.bind(this.client), + this.client.getIdentityBalance = promisify( + this.client.getIdentityBalance.bind(this.client), ); this.protocolVersion = undefined; @@ -733,8 +733,8 @@ class PlatformPromiseClient { ); } - getStatus( - getStatusRequest, + getIdentityBalance( + getIdentityBalanceRequest, metadata = {}, options = {}, ) { @@ -742,18 +742,18 @@ class PlatformPromiseClient { throw new Error('metadata must be an object'); } - return this.client.getStatus( - getStatusRequest, + return this.client.getIdentityBalance( + getIdentityBalanceRequest, convertObjectToMetadata(metadata), { interceptors: [ jsonToProtobufInterceptorFactory( jsonToProtobufFactory( - ProtocGetStatusResponse, - PBJSGetStatusResponse, + ProtocGetIdentityBalanceResponse, + PBJSGetIdentityBalanceResponse, ), protobufToJsonFactory( - PBJSGetStatusRequest, + PBJSGetIdentityBalanceRequest, ), ), ], diff --git a/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js b/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js index 035b7afbfc..77431b83bc 100644 --- a/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js +++ b/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js @@ -14,7 +14,7 @@ const getIdentityContractNonceFactory = require('./getIdentityContractNonce/getI const getIdentityNonceFactory = require('./getIdentityNonce/getIdentityNonceFactory'); const getIdentityKeysFactory = require('./getIdentityKeys/getIdentityKeysFactory'); const getTotalCreditsInPlatformFactory = require('./getTotalCreditsInPlatform/getTotalCreditsInPlatformFactory'); -const getStatusFactory = require('./getStatus/getStatusFactory'); +const getIdentityBalanceFactory = require('./getIdentityBalance/getIdentityBalanceFactory'); class PlatformMethodsFacade { /** @@ -39,7 +39,7 @@ class PlatformMethodsFacade { this.getIdentityNonce = getIdentityNonceFactory(grpcTransport); this.getIdentityKeys = getIdentityKeysFactory(grpcTransport); this.getTotalCreditsInPlatform = getTotalCreditsInPlatformFactory(grpcTransport); - this.getStatus = getStatusFactory(grpcTransport); + this.getIdentityBalance = getIdentityBalanceFactory(grpcTransport); } } diff --git a/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js new file mode 100644 index 0000000000..50c3ee3be3 --- /dev/null +++ b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js @@ -0,0 +1,43 @@ +const AbstractResponse = require('../response/AbstractResponse'); +const InvalidResponseError = require('../response/errors/InvalidResponseError'); + +class GetIdentityBalanceResponse extends AbstractResponse { + /** + * @param {Buffer} identity + * @param {Metadata} metadata + * @param {Proof} [proof] + */ + constructor(balance, metadata, proof = undefined) { + super(metadata, proof); + + this.balance = balance; + } + + /** + * @returns {Buffer} + */ + getIdentity() { + return this.balance; + } + + /** + * @param proto + * @returns {GetIdentityBalanceResponse} + */ + static createFromProto(proto) { + const balance = proto.getV0().getBalance(); + const { metadata, proof } = AbstractResponse.createMetadataAndProofFromProto(proto); + + if (!balance && !proof) { + throw new InvalidResponseError('Balance is not defined'); + } + + return new GetIdentityBalanceResponse( + balance, + metadata, + proof, + ); + } +} + +module.exports = GetIdentityBalanceResponse; diff --git a/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/getIdentityBalanceFactory.js b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/getIdentityBalanceFactory.js new file mode 100644 index 0000000000..93862ccff9 --- /dev/null +++ b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/getIdentityBalanceFactory.js @@ -0,0 +1,71 @@ +const { + v0: { + PlatformPromiseClient, + GetIdentityBalanceRequest, + }, +} = require('@dashevo/dapi-grpc'); + +const GetIdentityBalanceResponse = require('./GetIdentityBalanceResponse'); +const InvalidResponseError = require('../response/errors/InvalidResponseError'); + +/** + * @param {GrpcTransport} grpcTransport + * @returns {getIdentityBalance} + */ +function getIdentityBalanceFactory(grpcTransport) { + /** + * Fetch the identity balance by id + * @typedef {getIdentityBalance} + * @param {Buffer} id + * @param {DAPIClientOptions & {prove: boolean}} [options] + * @returns {Promise} + */ + async function getIdentityBalance(id, options = {}) { + const { GetIdentityBalanceRequestV0 } = GetIdentityBalanceRequest; + const getIdentityBalanceRequest = new GetIdentityBalanceRequest(); + // need to convert objects inherited from Buffer to pure buffer as google protobuf + // doesn't support extended buffers + // https://github.com/protocolbuffers/protobuf/blob/master/js/binary/utils.js#L1049 + if (Buffer.isBuffer(id)) { + // eslint-disable-next-line no-param-reassign + id = Buffer.from(id); + } + + getIdentityBalanceRequest.setV0( + new GetIdentityBalanceRequestV0() + .setId(id) + .setProve(!!options.prove), + ); + + let lastError; + + // TODO: simple retry before the dapi versioning is properly implemented + for (let i = 0; i < 3; i += 1) { + try { + // eslint-disable-next-line no-await-in-loop + const getIdentityBalanceResponse = await grpcTransport.request( + PlatformPromiseClient, + 'getIdentityBalance', + getIdentityBalanceRequest, + options, + ); + + return GetIdentityBalanceResponse.createFromProto(getIdentityBalanceResponse); + } catch (e) { + if (e instanceof InvalidResponseError) { + lastError = e; + } else { + throw e; + } + } + } + + // If we made it past the cycle it means that the retry didn't work, + // and we're throwing the last error encountered + throw lastError; + } + + return getIdentityBalance; +} + +module.exports = getIdentityBalanceFactory; From af456d572b8b67cecd112d19a7ab65dd83e6a5b1 Mon Sep 17 00:00:00 2001 From: owl352 Date: Wed, 4 Sep 2024 00:09:15 +0300 Subject: [PATCH 2/7] status fix --- .../v0/nodejs/PlatformPromiseClient.js | 36 +++++++++++++++++++ .../methods/platform/PlatformMethodsFacade.js | 2 ++ 2 files changed, 38 insertions(+) diff --git a/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js b/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js index 4047b47aca..a6190b4ac7 100644 --- a/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js +++ b/packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js @@ -60,6 +60,8 @@ const { GetIdentityKeysResponse: PBJSGetIdentityKeysResponse, GetTotalCreditsInPlatformRequest: PBJSGetTotalCreditsInPlatformRequest, GetTotalCreditsInPlatformResponse: PBJSGetTotalCreditsInPlatformResponse, + GetStatusRequest: PBJSGetStatusRequest, + GetStatusResponse: PBJSGetStatusResponse, GetIdentityBalanceRequest: PBJSGetIdentityBalanceRequest, GetIdentityBalanceResponse: PBJSGetIdentityBalanceResponse, }, @@ -87,6 +89,7 @@ const { GetIdentityNonceResponse: ProtocGetIdentityNonceResponse, GetIdentityKeysResponse: ProtocGetIdentityKeysResponse, GetTotalCreditsInPlatformResponse: ProtocGetTotalCreditsInPlatformResponse, + GetStatusResponse: ProtocGetStatusResponse, GetIdentityBalanceResponse: ProtocGetIdentityBalanceResponse, } = require('./platform_protoc'); @@ -182,6 +185,10 @@ class PlatformPromiseClient { this.client.getTotalCreditsInPlatform.bind(this.client), ); + this.client.getStatus = promisify( + this.client.getStatus.bind(this.client), + ); + this.client.getIdentityBalance = promisify( this.client.getIdentityBalance.bind(this.client), ); @@ -733,6 +740,35 @@ class PlatformPromiseClient { ); } + getStatus( + getStatusRequest, + metadata = {}, + options = {}, + ) { + if (!isObject(metadata)) { + throw new Error('metadata must be an object'); + } + + return this.client.getStatus( + getStatusRequest, + convertObjectToMetadata(metadata), + { + interceptors: [ + jsonToProtobufInterceptorFactory( + jsonToProtobufFactory( + ProtocGetStatusResponse, + PBJSGetStatusResponse, + ), + protobufToJsonFactory( + PBJSGetStatusRequest, + ), + ), + ], + ...options, + }, + ); + } + getIdentityBalance( getIdentityBalanceRequest, metadata = {}, diff --git a/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js b/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js index 77431b83bc..8de255abde 100644 --- a/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js +++ b/packages/js-dapi-client/lib/methods/platform/PlatformMethodsFacade.js @@ -14,6 +14,7 @@ const getIdentityContractNonceFactory = require('./getIdentityContractNonce/getI const getIdentityNonceFactory = require('./getIdentityNonce/getIdentityNonceFactory'); const getIdentityKeysFactory = require('./getIdentityKeys/getIdentityKeysFactory'); const getTotalCreditsInPlatformFactory = require('./getTotalCreditsInPlatform/getTotalCreditsInPlatformFactory'); +const getStatusFactory = require('./getStatus/getStatusFactory'); const getIdentityBalanceFactory = require('./getIdentityBalance/getIdentityBalanceFactory'); class PlatformMethodsFacade { @@ -39,6 +40,7 @@ class PlatformMethodsFacade { this.getIdentityNonce = getIdentityNonceFactory(grpcTransport); this.getIdentityKeys = getIdentityKeysFactory(grpcTransport); this.getTotalCreditsInPlatform = getTotalCreditsInPlatformFactory(grpcTransport); + this.getStatus = getStatusFactory(grpcTransport); this.getIdentityBalance = getIdentityBalanceFactory(grpcTransport); } } From f56517b18eef18e32ec04d1a293e5750370c382d Mon Sep 17 00:00:00 2001 From: owl352 Date: Wed, 4 Sep 2024 00:36:56 +0300 Subject: [PATCH 3/7] epoch start fix --- .../lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js b/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js index 9ae984dbc9..91befa54e8 100644 --- a/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js +++ b/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js @@ -28,7 +28,7 @@ function getEpochsInfoFactory(grpcTransport) { const getEpochInfosRequest = new GetEpochsInfoRequest(); getEpochInfosRequest.setV0( new GetEpochsInfoRequestV0() - .setStartEpoch(new UInt32Value([startEpoch])) + .setStartEpoch(startEpoch ? new UInt32Value([startEpoch]) : undefined) .setCount(count) .setAscending(!!options.ascending) .setProve(!!options.prove), From 4131d1dd23fd8a5a41ae7fedbf967e22b1886ab0 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Wed, 4 Sep 2024 22:41:27 +0700 Subject: [PATCH 4/7] feat(dapi-grpc): add unit test for getIdentityBalance() --- .../platform/v0/nodejs/PlatformPromiseClient.spec.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/dapi-grpc/test/unit/clients/platform/v0/nodejs/PlatformPromiseClient.spec.js b/packages/dapi-grpc/test/unit/clients/platform/v0/nodejs/PlatformPromiseClient.spec.js index 5987cbfd0f..fc3eb575fa 100644 --- a/packages/dapi-grpc/test/unit/clients/platform/v0/nodejs/PlatformPromiseClient.spec.js +++ b/packages/dapi-grpc/test/unit/clients/platform/v0/nodejs/PlatformPromiseClient.spec.js @@ -22,6 +22,7 @@ describe('PlatformPromiseClient', () => { getIdentityContractNonce: this.sinon.stub().resolves(response), getIdentityNonce: this.sinon.stub().resolves(response), getIdentityKeys: this.sinon.stub().resolves(response), + getIdentityBalance: this.sinon.stub().resolves(response), }; }); @@ -170,4 +171,14 @@ describe('PlatformPromiseClient', () => { .to.be.calledOnceWith(request); }); }); + + describe('#getIdentityBalance', () => { + it('should get identity balance', async () => { + const result = await platformPromiseClient.getIdentityBalance(request); + + expect(result).to.equal(response); + expect(platformPromiseClient.client.getIdentityBalance) + .to.be.calledOnceWith(request); + }); + }); }); From ef1f0484d9d2b54fcb4f1f551b1321cae9521371 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Thu, 5 Sep 2024 00:30:33 +0700 Subject: [PATCH 5/7] feat(js-dapi-client): add unit and integration tests for getIdentityBalance --- .../GetIdentityBalanceResponse.js | 6 +- .../platform/PlatformMethodsFacade.spec.js | 20 +++ .../GetIdentityBalanceResponse.spec.js | 126 ++++++++++++++ .../getIdentityBalanceFactory.spec.js | 156 ++++++++++++++++++ 4 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.spec.js create mode 100644 packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/getIdentityBalanceFactory.spec.js diff --git a/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js index 50c3ee3be3..ef1d0b9a97 100644 --- a/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js +++ b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js @@ -3,7 +3,7 @@ const InvalidResponseError = require('../response/errors/InvalidResponseError'); class GetIdentityBalanceResponse extends AbstractResponse { /** - * @param {Buffer} identity + * @param {number} balance * @param {Metadata} metadata * @param {Proof} [proof] */ @@ -14,9 +14,9 @@ class GetIdentityBalanceResponse extends AbstractResponse { } /** - * @returns {Buffer} + * @returns {number} */ - getIdentity() { + getBalance() { return this.balance; } diff --git a/packages/js-dapi-client/test/integration/methods/platform/PlatformMethodsFacade.spec.js b/packages/js-dapi-client/test/integration/methods/platform/PlatformMethodsFacade.spec.js index cb2c2dd0fa..fbb1f32ed5 100644 --- a/packages/js-dapi-client/test/integration/methods/platform/PlatformMethodsFacade.spec.js +++ b/packages/js-dapi-client/test/integration/methods/platform/PlatformMethodsFacade.spec.js @@ -4,6 +4,7 @@ const { GetDataContractResponse, GetDocumentsResponse, GetIdentityResponse, + GetIdentityBalanceResponse, GetIdentityByPublicKeyHashResponse, GetIdentitiesContractKeysResponse, GetEpochsInfoResponse, @@ -27,6 +28,7 @@ const PlatformMethodsFacade = require('../../../../lib/methods/platform/Platform const { WaitForStateTransitionResultResponseV0 } = WaitForStateTransitionResultResponse; const { GetIdentityResponseV0 } = GetIdentityResponse; +const { GetIdentityBalanceResponseV0 } = GetIdentityBalanceResponse; const { GetIdentityByPublicKeyHashResponseV0 } = GetIdentityByPublicKeyHashResponse; const { GetIdentitiesContractKeysResponseV0 } = GetIdentitiesContractKeysResponse; const { GetDocumentsResponseV0 } = GetDocumentsResponse; @@ -318,4 +320,22 @@ describe('PlatformMethodsFacade', () => { expect(grpcTransportMock.request).to.be.calledOnce(); }); }); + + describe('#getIdentityBalance', () => { + it('should get identity balance', async () => { + const response = new GetIdentityBalanceResponse(); + + response.setV0( + new GetIdentityBalanceResponseV0() + .setMetadata(new ResponseMetadata()) + .setBalance(1337), + ); + + grpcTransportMock.request.resolves(response); + + await platformMethods.getIdentityBalance('41nthkqvHBLnqiMkSbsdTNANzYu9bgdv4etKoRUunY1M'); + + expect(grpcTransportMock.request).to.be.calledOnce(); + }); + }); }); diff --git a/packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.spec.js b/packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.spec.js new file mode 100644 index 0000000000..3df6adb6be --- /dev/null +++ b/packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.spec.js @@ -0,0 +1,126 @@ +const { + v0: { + GetIdentityBalanceResponse, + ResponseMetadata, + Proof: ProofResponse, + }, +} = require('@dashevo/dapi-grpc'); + +const GetIdentityBalanceResponseClass = require('../../../../../lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse'); +const getMetadataFixture = require('../../../../../lib/test/fixtures/getMetadataFixture'); +const InvalidResponseError = require('../../../../../lib/methods/platform/response/errors/InvalidResponseError'); +const getProofFixture = require('../../../../../lib/test/fixtures/getProofFixture'); +const Proof = require('../../../../../lib/methods/platform/response/Proof'); +const Metadata = require('../../../../../lib/methods/platform/response/Metadata'); + +describe('GetIdentityBalanceResponse', () => { + let getIdentityBalanceResponse; + let metadataFixture; + let balance; + let proto; + let proofFixture; + + beforeEach(async () => { + metadataFixture = getMetadataFixture(); + proofFixture = getProofFixture(); + balance = 1337; + + const { GetIdentityBalanceResponseV0 } = GetIdentityBalanceResponse; + proto = new GetIdentityBalanceResponse(); + + const metadata = new ResponseMetadata(); + metadata.setHeight(metadataFixture.height); + metadata.setCoreChainLockedHeight(metadataFixture.coreChainLockedHeight); + metadata.setTimeMs(metadataFixture.timeMs); + metadata.setProtocolVersion(metadataFixture.protocolVersion); + + proto.setV0( + new GetIdentityBalanceResponseV0() + .setBalance(balance) + .setMetadata(metadata), + ); + + getIdentityBalanceResponse = new GetIdentityBalanceResponseClass( + balance, + new Metadata(metadataFixture), + ); + }); + + it('should return Identity balance', () => { + const identityBalance = getIdentityBalanceResponse.getBalance(); + const identityProof = getIdentityBalanceResponse.getProof(); + + expect(identityBalance).to.equal(balance); + expect(identityProof).to.equal(undefined); + }); + + it('should return proof', () => { + getIdentityBalanceResponse = new GetIdentityBalanceResponseClass( + balance, + new Metadata(metadataFixture), + new Proof(proofFixture), + ); + + const identityBalance = getIdentityBalanceResponse.getBalance(); + const proof = getIdentityBalanceResponse.getProof(); + + expect(identityBalance).to.equal(balance); + expect(proof).to.be.an.instanceOf(Proof); + expect(proof.getGrovedbProof()).to.deep.equal(proofFixture.merkleProof); + expect(proof.getQuorumHash()).to.deep.equal(proofFixture.quorumHash); + expect(proof.getSignature()).to.deep.equal(proofFixture.signature); + expect(proof.getRound()).to.deep.equal(proofFixture.round); + }); + + it('should create an instance from proto', () => { + getIdentityBalanceResponse = GetIdentityBalanceResponseClass.createFromProto(proto); + expect(getIdentityBalanceResponse).to.be + .an.instanceOf(GetIdentityBalanceResponseClass); + expect(getIdentityBalanceResponse.getBalance()).to.equal(balance); + + expect(getIdentityBalanceResponse.getMetadata()) + .to.be.an.instanceOf(Metadata); + expect(getIdentityBalanceResponse.getMetadata().getHeight()) + .to.equal(metadataFixture.height); + expect(getIdentityBalanceResponse.getMetadata().getCoreChainLockedHeight()) + .to.equal(metadataFixture.coreChainLockedHeight); + + expect(getIdentityBalanceResponse.getProof()).to.equal(undefined); + }); + + it('should create an instance with proof from proto', () => { + const proofProto = new ProofResponse(); + + proofProto.setQuorumHash(proofFixture.quorumHash); + proofProto.setSignature(proofFixture.signature); + proofProto.setGrovedbProof(proofFixture.merkleProof); + proofProto.setRound(proofFixture.round); + + proto.getV0().setBalance(undefined); + proto.getV0().setProof(proofProto); + + getIdentityBalanceResponse = GetIdentityBalanceResponseClass.createFromProto(proto); + + expect(getIdentityBalanceResponse.getBalance()).to.equal(0); + expect(getIdentityBalanceResponse.getMetadata()).to.deep.equal(metadataFixture); + + const proof = getIdentityBalanceResponse.getProof(); + expect(proof).to.be.an.instanceOf(Proof); + expect(proof.getGrovedbProof()).to.deep.equal(proofFixture.merkleProof); + expect(proof.getQuorumHash()).to.deep.equal(proofFixture.quorumHash); + expect(proof.getSignature()).to.deep.equal(proofFixture.signature); + expect(proof.getRound()).to.deep.equal(proofFixture.round); + }); + + it('should throw InvalidResponseError if Metadata is not defined', () => { + proto.getV0().setMetadata(undefined); + + try { + getIdentityBalanceResponse = GetIdentityBalanceResponseClass.createFromProto(proto); + + expect.fail('should throw InvalidResponseError'); + } catch (e) { + expect(e).to.be.an.instanceOf(InvalidResponseError); + } + }); +}); diff --git a/packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/getIdentityBalanceFactory.spec.js b/packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/getIdentityBalanceFactory.spec.js new file mode 100644 index 0000000000..210d2a8a9f --- /dev/null +++ b/packages/js-dapi-client/test/unit/methods/platform/getIdentityBalance/getIdentityBalanceFactory.spec.js @@ -0,0 +1,156 @@ +const { + v0: { + PlatformPromiseClient, + GetIdentityBalanceRequest, + GetIdentityBalanceResponse, + ResponseMetadata, + Proof: ProofResponse, + }, +} = require('@dashevo/dapi-grpc'); + +const { GetIdentityBalanceResponseV0 } = GetIdentityBalanceResponse; + +const getIdentityBalanceFactory = require('../../../../../lib/methods/platform/getIdentityBalance/getIdentityBalanceFactory'); +const getMetadataFixture = require('../../../../../lib/test/fixtures/getMetadataFixture'); +const getProofFixture = require('../../../../../lib/test/fixtures/getProofFixture'); +const Proof = require('../../../../../lib/methods/platform/response/Proof'); + +describe('getIdentityBalanceFactory', () => { + let grpcTransportMock; + let getIdentityBalance; + let options; + let response; + let balance; + let identityId; + let metadataFixture; + let proofFixture; + let proofResponse; + + beforeEach(async function beforeEach() { + balance = 1337; + + identityId = Buffer.alloc(32).fill(0); + + metadataFixture = getMetadataFixture(); + proofFixture = getProofFixture(); + + const metadata = new ResponseMetadata(); + metadata.setHeight(metadataFixture.height); + metadata.setCoreChainLockedHeight(metadataFixture.coreChainLockedHeight); + metadata.setTimeMs(metadataFixture.timeMs); + metadata.setProtocolVersion(metadataFixture.protocolVersion); + + response = new GetIdentityBalanceResponse(); + + response.setV0( + new GetIdentityBalanceResponseV0() + .setBalance(balance) + .setMetadata(metadata), + ); + + proofResponse = new ProofResponse(); + + proofResponse.setQuorumHash(proofFixture.quorumHash); + proofResponse.setSignature(proofFixture.signature); + proofResponse.setGrovedbProof(proofFixture.merkleProof); + proofResponse.setRound(proofFixture.round); + + grpcTransportMock = { + request: this.sinon.stub().resolves(response), + }; + + getIdentityBalance = getIdentityBalanceFactory(grpcTransportMock); + + options = { + timeout: 1000, + }; + }); + + it('should return identity balance', async () => { + const result = await getIdentityBalance(identityId, options); + + const { GetIdentityBalanceRequestV0 } = GetIdentityBalanceRequest; + const request = new GetIdentityBalanceRequest(); + request.setV0( + new GetIdentityBalanceRequestV0() + .setId(identityId) + .setProve(false), + ); + + expect(grpcTransportMock.request).to.be.calledOnceWithExactly( + PlatformPromiseClient, + 'getIdentityBalance', + request, + options, + ); + expect(result.getBalance()).to.deep.equal(balance); + expect(result.getMetadata()).to.deep.equal(metadataFixture); + expect(result.getProof()).to.equal(undefined); + }); + + it('should return proof', async () => { + options.prove = true; + response.getV0().setBalance(undefined); + response.getV0().setProof(proofResponse); + + const result = await getIdentityBalance(identityId, options); + + const { GetIdentityBalanceRequestV0 } = GetIdentityBalanceRequest; + const request = new GetIdentityBalanceRequest(); + request.setV0( + new GetIdentityBalanceRequestV0() + .setId(identityId) + .setProve(true), + ); + + expect(grpcTransportMock.request).to.be.calledOnceWithExactly( + PlatformPromiseClient, + 'getIdentityBalance', + request, + options, + ); + + expect(result.getBalance()).to.deep.equal(0); + + expect(result.getMetadata()).to.deep.equal(metadataFixture); + + expect(result.getProof()).to.be.an.instanceOf(Proof); + expect(result.getProof().getGrovedbProof()).to.deep.equal(proofFixture.merkleProof); + expect(result.getProof().getQuorumHash()).to.deep.equal(proofFixture.quorumHash); + expect(result.getProof().getSignature()).to.deep.equal(proofFixture.signature); + expect(result.getProof().getRound()).to.deep.equal(proofFixture.round); + expect(result.getMetadata()).to.deep.equal(metadataFixture); + expect(result.getMetadata().getHeight()).to.equal(metadataFixture.height); + expect(result.getMetadata().getCoreChainLockedHeight()).to.equal( + metadataFixture.coreChainLockedHeight, + ); + }); + + it('should throw unknown error', async () => { + const error = new Error('Unknown found'); + + grpcTransportMock.request.throws(error); + + const { GetIdentityBalanceRequestV0 } = GetIdentityBalanceRequest; + const request = new GetIdentityBalanceRequest(); + request.setV0( + new GetIdentityBalanceRequestV0() + .setId(identityId) + .setProve(false), + ); + + try { + await getIdentityBalance(identityId, options); + + expect.fail('should throw unknown error'); + } catch (e) { + expect(e).to.deep.equal(error); + expect(grpcTransportMock.request).to.be.calledOnceWithExactly( + PlatformPromiseClient, + 'getIdentityBalance', + request, + options, + ); + } + }); +}); From e4e2450f967d0b1db8eadc9490bffdb6645fdf9c Mon Sep 17 00:00:00 2001 From: pshenmic Date: Thu, 5 Sep 2024 03:21:45 +0700 Subject: [PATCH 6/7] fix(js-dapi-client): improve null check --- .../platform/getIdentityBalance/GetIdentityBalanceResponse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js index ef1d0b9a97..b5b4a59b31 100644 --- a/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js +++ b/packages/js-dapi-client/lib/methods/platform/getIdentityBalance/GetIdentityBalanceResponse.js @@ -28,7 +28,7 @@ class GetIdentityBalanceResponse extends AbstractResponse { const balance = proto.getV0().getBalance(); const { metadata, proof } = AbstractResponse.createMetadataAndProofFromProto(proto); - if (!balance && !proof) { + if ((balance === null || balance === undefined) && !proof) { throw new InvalidResponseError('Balance is not defined'); } From ac0dfdef3145fce30f6bab395f6f39611610b557 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Tue, 17 Sep 2024 22:44:37 +0700 Subject: [PATCH 7/7] fix(dapi): improve null check --- .../lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js b/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js index 91befa54e8..9982c6f9e6 100644 --- a/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js +++ b/packages/js-dapi-client/lib/methods/platform/getEpochsInfo/getEpochsInfoFactory.js @@ -28,7 +28,7 @@ function getEpochsInfoFactory(grpcTransport) { const getEpochInfosRequest = new GetEpochsInfoRequest(); getEpochInfosRequest.setV0( new GetEpochsInfoRequestV0() - .setStartEpoch(startEpoch ? new UInt32Value([startEpoch]) : undefined) + .setStartEpoch(typeof startEpoch === 'number' ? new UInt32Value([startEpoch]) : undefined) .setCount(count) .setAscending(!!options.ascending) .setProve(!!options.prove),