diff --git a/src/transaction/TransactionReceipt.js b/src/transaction/TransactionReceipt.js index 4fe65c8d0..816529638 100644 --- a/src/transaction/TransactionReceipt.js +++ b/src/transaction/TransactionReceipt.js @@ -45,6 +45,7 @@ import * as hex from "../encoding/hex.js"; * @property {?string} tokenId * @property {?string} scheduleId * @property {?ExchangeRateJSON} exchangeRate + * @property {?ExchangeRateJSON} nextExchangeRate * @property {?string} topicSequenceNumber * @property {?string} topicRunningHash * @property {?string} totalSupply @@ -71,6 +72,7 @@ export default class TransactionReceipt { * @param {?TokenId} props.tokenId * @param {?ScheduleId} props.scheduleId * @param {?ExchangeRate} props.exchangeRate + * @param {?ExchangeRate} props.nextExchangeRate * @param {?Long} props.topicSequenceNumber * @param {?Uint8Array} props.topicRunningHash * @param {?Long} props.totalSupply @@ -137,6 +139,13 @@ export default class TransactionReceipt { */ this.exchangeRate = props.exchangeRate; + /** + * The next exchange rate of Hbars to cents (USD). + * + * @readonly + */ + this.nextExchangeRate = props.nextExchangeRate; + /** * Updated sequence number for a consensus service topic. * @@ -236,7 +245,10 @@ export default class TransactionReceipt { topicSequenceNumber: this.topicSequenceNumber, exchangeRate: { - nextRate: null, + nextRate: + this.nextExchangeRate != null + ? this.nextExchangeRate._toProtobuf() + : null, currentRate: this.exchangeRate != null ? this.exchangeRate._toProtobuf() @@ -266,11 +278,6 @@ export default class TransactionReceipt { response.receipt ); - const exchangeRateSet = - /** @type {HashgraphProto.proto.IExchangeRateSet} */ ( - receipt.exchangeRate - ); - const children = response.childTransactionReceipts != null ? response.childTransactionReceipts.map((child) => @@ -324,7 +331,15 @@ export default class TransactionReceipt { receipt.exchangeRate != null ? ExchangeRate._fromProtobuf( /** @type {HashgraphProto.proto.IExchangeRate} */ - (exchangeRateSet.currentRate), + (receipt.exchangeRate.currentRate), + ) + : null, + + nextExchangeRate: + receipt.exchangeRate != null + ? ExchangeRate._fromProtobuf( + /** @type {HashgraphProto.proto.IExchangeRate} */ + (receipt.exchangeRate.nextRate), ) : null, @@ -393,6 +408,7 @@ export default class TransactionReceipt { tokenId: this.tokenId?.toString() || null, scheduleId: this.scheduleId?.toString() || null, exchangeRate: this.exchangeRate?.toJSON() || null, + nextExchangeRate: this.nextExchangeRate?.toJSON() || null, topicSequenceNumber: this.topicSequenceNumber?.toString() || null, topicRunningHash: this.topicRunningHash != null diff --git a/test/integration/TransactionResponseTest.js b/test/integration/TransactionResponseTest.js index 6a14c73c2..b7e3ac73d 100644 --- a/test/integration/TransactionResponseTest.js +++ b/test/integration/TransactionResponseTest.js @@ -101,6 +101,21 @@ describe("TransactionResponse", function () { ).getReceipt(env.client); }); + it("should return nextExchangeRate in receipt", async function () { + const operatorId = env.operatorId; + expect(operatorId).to.not.be.null; + + const key = PrivateKey.generateED25519(); + + const receipt = await ( + await new AccountCreateTransaction() + .setKey(key.publicKey) + .execute(env.client) + ).getReceipt(env.client); + + expect(receipt.nextExchangeRate).to.not.be.null; + }); + after(async function () { await env.close(); }); diff --git a/test/unit/TransactionReceipt.js b/test/unit/TransactionReceipt.js index 25ff9bbcf..7c05537c1 100644 --- a/test/unit/TransactionReceipt.js +++ b/test/unit/TransactionReceipt.js @@ -4,6 +4,7 @@ import { AccountId, ContractId, ExchangeRate, + ExchangeRates, FileId, ScheduleId, Status, @@ -25,10 +26,20 @@ describe("TransactionReceipt", function () { const tokenId = TokenId.fromString("0.0.4"); const scheduleId = ScheduleId.fromString("0.0.5"); const exchangeRate = new ExchangeRate({ + hbars: 3, + cents: 4, + expirationTime: new Date(5), + }); + const nextExchangeRate = new ExchangeRate({ hbars: 6, cents: 7, expirationTime: new Date(8), }); + const exchangeRateSet = new ExchangeRates({ + currentRate: exchangeRate, + nextRate: nextExchangeRate, + }); + const topicSequenceNumber = Long.fromNumber(9); const topicRunningHash = new Uint8Array([10]); const totalSupply = Long.fromNumber(11); @@ -48,6 +59,7 @@ describe("TransactionReceipt", function () { tokenId, scheduleId, exchangeRate, + nextExchangeRate, topicSequenceNumber, topicRunningHash, totalSupply, @@ -77,10 +89,9 @@ describe("TransactionReceipt", function () { expect(receipt.receipt.topicSequenceNumber).to.deep.equal( topicSequenceNumber, ); - expect(receipt.receipt.exchangeRate).to.deep.equal({ - currentRate: exchangeRate._toProtobuf(), - nextRate: null, - }); + expect(receipt.receipt.exchangeRate).to.deep.equal( + exchangeRateSet._toProtobuf(), + ); expect(receipt.receipt.scheduledTransactionID).to.deep.equal( scheduledTransactionId._toProtobuf(), ); @@ -103,6 +114,11 @@ describe("TransactionReceipt", function () { cents: 7, expirationTime: new Date(Date.parse("1973-11-25T17:31:44.000Z")), }); + const nextExchangeRate = new ExchangeRate({ + hbars: 2, + cents: 1, + expirationTime: new Date(Date.parse("1973-11-25T17:31:44.000Z")), + }); const topicSequenceNumber = Long.fromNumber(9); const topicRunningHash = new Uint8Array([10]); const totalSupply = Long.fromNumber(11); @@ -122,6 +138,7 @@ describe("TransactionReceipt", function () { tokenId, scheduleId, exchangeRate, + nextExchangeRate, topicSequenceNumber, topicRunningHash, totalSupply, @@ -142,7 +159,7 @@ describe("TransactionReceipt", function () { receipt.duplicates.push(child); const expectedJSON = JSON.parse( - `{"status":"OK","accountId":"0.0.1","filedId":"0.0.2","contractId":"0.0.3","topicId":"0.0.3","tokenId":"0.0.4","scheduleId":"0.0.5","exchangeRate":{"hbars":6,"cents":7,"expirationTime":"1973-11-25T17:31:44.000Z","exchangeRateInCents":1.1666666666666667},"topicSequenceNumber":"9","topicRunningHash":"0a","totalSupply":"11","scheduledTransactionId":"0.0.12@13.000000014","serials":["15"],"duplicates":[{"status":"OK","accountId":"0.0.1","filedId":"0.0.2","contractId":"0.0.3","topicId":"0.0.3","tokenId":null,"scheduleId":null,"exchangeRate":null,"topicSequenceNumber":null,"topicRunningHash":null,"totalSupply":null,"scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId": null}],"children":[{"status":"OK","accountId":"0.0.1","filedId":"0.0.2","contractId":"0.0.3","topicId":"0.0.3","tokenId":null,"scheduleId":null,"exchangeRate":null,"topicSequenceNumber":null,"topicRunningHash":null,"totalSupply":null,"scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId": null}], "nodeId": "1234"}`, + `{"status":"OK","accountId":"0.0.1","filedId":"0.0.2","contractId":"0.0.3","topicId":"0.0.3","tokenId":"0.0.4","scheduleId":"0.0.5","exchangeRate":{"hbars":6,"cents":7,"expirationTime":"1973-11-25T17:31:44.000Z","exchangeRateInCents":1.1666666666666667},"nextExchangeRate":{"hbars":2,"cents":1,"expirationTime":"1973-11-25T17:31:44.000Z","exchangeRateInCents":0.5},"topicSequenceNumber":"9","topicRunningHash":"0a","totalSupply":"11","scheduledTransactionId":"0.0.12@13.000000014","serials":["15"],"duplicates":[{"status":"OK","accountId":"0.0.1","filedId":"0.0.2","contractId":"0.0.3","topicId":"0.0.3","tokenId":null,"scheduleId":null,"exchangeRate":null,"nextExchangeRate":null,"topicSequenceNumber":null,"topicRunningHash":null,"totalSupply":null,"scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId":null}],"children":[{"status":"OK","accountId":"0.0.1","filedId":"0.0.2","contractId":"0.0.3","topicId":"0.0.3","tokenId":null,"scheduleId":null,"exchangeRate":null,"nextExchangeRate":null,"topicSequenceNumber":null,"topicRunningHash":null,"totalSupply":null,"scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId":null}],"nodeId":"1234"}`, ); const resultJSON = JSON.parse(JSON.stringify(receipt)); @@ -154,9 +171,8 @@ describe("TransactionReceipt", function () { const receipt = new TransactionReceipt({ status, }); - console.log(JSON.stringify(receipt)); - const expectedJSON = `{"status":"OK","accountId":null,"filedId":null,"contractId":null,"topicId":null,"tokenId":null,"scheduleId":null,"exchangeRate":null,"topicSequenceNumber":null,"topicRunningHash":null,"totalSupply":null,"scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId": null}`; + const expectedJSON = `{"status":"OK","accountId":null,"filedId":null,"contractId":null,"topicId":null,"tokenId":null,"scheduleId":null,"exchangeRate":null,"nextExchangeRate":null,"topicSequenceNumber":null,"topicRunningHash":null,"totalSupply":null,"scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId":null}`; const expectedJSONParsed = JSON.parse(expectedJSON); const resultJSON = JSON.parse(JSON.stringify(receipt)); diff --git a/test/unit/TransactionRecord.js b/test/unit/TransactionRecord.js index a3243e766..ddb1237a0 100644 --- a/test/unit/TransactionRecord.js +++ b/test/unit/TransactionRecord.js @@ -16,7 +16,7 @@ import TokenNFTTransferMap from "../../src/account/TokenNftTransferMap.js"; import * as hex from "../../src/encoding/hex.js"; const HEX_BYTES = - "1a80020a28081612070800100018de092a130a110801100c1a0b0880ae99a4ffffffffff0138004200580078001230cac44f2db045ba441f3fbc295217f2eb0f956293d28b3401578f6160e66f4e47ea87952d91c4b1cb5bda6447823b979a1a0c08f3fcb495061083d9be900322190a0c08e8fcb495061098f09cf20112070800100018850918002a0030bee8f013526c0a0f0a0608001000180510d0df820118000a0f0a0608001000186210f08dff1e18000a100a070800100018a00610def1ef0318000a100a070800100018a10610def1ef0318000a110a070800100018850910fbf8b7e10718000a110a070800100018de091080a8d6b90718008a0100aa0100"; + "1a93020a3b081612070800100018de092a260a110801100c1a0b0880ae99a4ffffffffff0112110801100f1a0b08c0bd98a4ffffffffff0138004200580078001230cac44f2db045ba441f3fbc295217f2eb0f956293d28b3401578f6160e66f4e47ea87952d91c4b1cb5bda6447823b979a1a0c08f3fcb495061083d9be900322190a0c08e8fcb495061098f09cf20112070800100018850918002a0030bee8f013526c0a0f0a0608001000180510d0df820118000a0f0a0608001000186210f08dff1e18000a100a070800100018a00610def1ef0318000a100a070800100018a10610def1ef0318000a110a070800100018850910fbf8b7e10718000a110a070800100018de091080a8d6b90718008a0100aa0100"; describe("TransactionRecord", function () { it("[from|to]Bytes()", function () { @@ -79,7 +79,7 @@ describe("TransactionRecord", function () { }); const expectedJSON = JSON.parse( - `{"receipt":{"status":"SUCCESS","accountId":"0.0.1246","filedId":null,"contractId":null,"topicId":null,"tokenId":null,"scheduleId":null,"exchangeRate":{"hbars":1,"cents":12,"expirationTime":"1963-11-25T17:31:44.000Z","exchangeRateInCents":12},"topicSequenceNumber":"0","topicRunningHash":"","totalSupply":"0","scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId":"0"},"transactionHash":"cac44f2db045ba441f3fbc295217f2eb0f956293d28b3401578f6160e66f4e47ea87952d91c4b1cb5bda6447823b979a","consensusTimestamp":"2022-06-18T02:54:43.839Z","transactionId":"0.0.1157@1655520872.507983896","transactionMemo":"test","transactionFee":"41694270","transfers":[{"accountId":"0.0.5","amount":"1071080","isApproved":false},{"accountId":"0.0.98","amount":"32498552","isApproved":false},{"accountId":"0.0.800","amount":"4062319","isApproved":false},{"accountId":"0.0.801","amount":"4062319","isApproved":false},{"accountId":"0.0.1157","amount":"-1041694270","isApproved":false},{"accountId":"0.0.1246","amount":"1000000000","isApproved":false}],"tokenTransfers":{"0.0.123":{"0.0.1246":"789"}},"tokenTransfersList":[{"tokenId":"0.0.123","accountId":"0.0.1246","amount":"789"}],"scheduleRef":"0.0.123","assessedCustomFees":[{"feeCollectorAccountId":"0.0.1246","tokenId":"0.0.123","amount":"789","payerAccountIds":["0.0.1246"]}],"nftTransfers":{"0.0.123":[{"sender":"0.0.1246","recipient":"0.0.1246","serial":123,"isApproved":true}]},"automaticTokenAssociations":[{"accountId":"0.0.1246","tokenId":"0.0.123"}],"parentConsensusTimestamp":"2022-06-18T02:54:43.839Z","aliasKey":"302a300506032b6570032100d7366c45e4d2f1a6c1d9af054f5ef8edc0b8d3875ba5d08a7f2e81ee8876e9e8","duplicates":[],"children":[],"ethereumHash":"01020304","paidStakingRewards":[{"accountId":"0.0.5","amount":"1071080","isApproved":false},{"accountId":"0.0.98","amount":"32498552","isApproved":false},{"accountId":"0.0.800","amount":"4062319","isApproved":false},{"accountId":"0.0.801","amount":"4062319","isApproved":false},{"accountId":"0.0.1157","amount":"-1041694270","isApproved":false},{"accountId":"0.0.1246","amount":"1000000000","isApproved":false}],"prngBytes":"01020304","prngNumber":123,"evmAddress":"deadbeef"}`, + `{"receipt":{"status":"SUCCESS","accountId":"0.0.1246","filedId":null,"contractId":null,"topicId":null,"tokenId":null,"scheduleId":null,"exchangeRate":{"hbars":1,"cents":12,"expirationTime":"1963-11-25T17:31:44.000Z","exchangeRateInCents":12},"nextExchangeRate":{"hbars":1,"cents":15,"expirationTime":"1963-11-25T13:31:44.000Z","exchangeRateInCents":15},"topicSequenceNumber":"0","topicRunningHash":"","totalSupply":"0","scheduledTransactionId":null,"serials":[],"duplicates":[],"children":[],"nodeId":"0"},"transactionHash":"cac44f2db045ba441f3fbc295217f2eb0f956293d28b3401578f6160e66f4e47ea87952d91c4b1cb5bda6447823b979a","consensusTimestamp":"2022-06-18T02:54:43.839Z","transactionId":"0.0.1157@1655520872.507983896","transactionMemo":"test","transactionFee":"41694270","transfers":[{"accountId":"0.0.5","amount":"1071080","isApproved":false},{"accountId":"0.0.98","amount":"32498552","isApproved":false},{"accountId":"0.0.800","amount":"4062319","isApproved":false},{"accountId":"0.0.801","amount":"4062319","isApproved":false},{"accountId":"0.0.1157","amount":"-1041694270","isApproved":false},{"accountId":"0.0.1246","amount":"1000000000","isApproved":false}],"tokenTransfers":{"0.0.123":{"0.0.1246":"789"}},"tokenTransfersList":[{"tokenId":"0.0.123","accountId":"0.0.1246","amount":"789"}],"scheduleRef":"0.0.123","assessedCustomFees":[{"feeCollectorAccountId":"0.0.1246","tokenId":"0.0.123","amount":"789","payerAccountIds":["0.0.1246"]}],"nftTransfers":{"0.0.123":[{"sender":"0.0.1246","recipient":"0.0.1246","serial":123,"isApproved":true}]},"automaticTokenAssociations":[{"accountId":"0.0.1246","tokenId":"0.0.123"}],"parentConsensusTimestamp":"2022-06-18T02:54:43.839Z","aliasKey":"302a300506032b6570032100d7366c45e4d2f1a6c1d9af054f5ef8edc0b8d3875ba5d08a7f2e81ee8876e9e8","duplicates":[],"children":[],"ethereumHash":"01020304","paidStakingRewards":[{"accountId":"0.0.5","amount":"1071080","isApproved":false},{"accountId":"0.0.98","amount":"32498552","isApproved":false},{"accountId":"0.0.800","amount":"4062319","isApproved":false},{"accountId":"0.0.801","amount":"4062319","isApproved":false},{"accountId":"0.0.1157","amount":"-1041694270","isApproved":false},{"accountId":"0.0.1246","amount":"1000000000","isApproved":false}],"prngBytes":"01020304","prngNumber":123,"evmAddress":"deadbeef"}`, ); const actualJSON = JSON.parse(JSON.stringify(newRecord));