diff --git a/CHANGELOG.md b/CHANGELOG.md index 26d9bccee..98edfafa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,529 +1,557 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v2.20.0 + +## What's Changed + +- Add new status codes by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1400 +- chore(deps-dev): bump typescript from 4.9.4 to 4.9.5 in /examples/react-native-example by @dependabot in https://github.com/hashgraph/hedera-sdk-js/pull/1438 +- chore(deps): bump react-native from 0.71.1 to 0.71.2 in /examples/react-native-example by @dependabot in https://github.com/hashgraph/hedera-sdk-js/pull/1437 +- chore(deps): bump react-native-web from 0.18.10 to 0.18.12 in /examples/react-native-example by @dependabot in https://github.com/hashgraph/hedera-sdk-js/pull/1436 +- chore(deps): bump ua-parser-js from 0.7.31 to 0.7.33 in /examples/react-native-example by @dependabot in https://github.com/hashgraph/hedera-sdk-js/pull/1435 +- chore(deps): bump decode-uri-component from 0.2.0 to 0.2.2 in /examples/react-native-example by @dependabot in https://github.com/hashgraph/hedera-sdk-js/pull/1434 +- Fix \_maxAutomaticTokenAssociations in contract create and contract up… by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1444 +- Feature/extend ethereumflow by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1447 +- Fix/timeout issue by @ochikov in #1414 +- Updated Protobuf statuses +- fix ping to throw by @ochikov in #1426 +- Bump up dependencies by @ochikov in #1402 +- Removed unnecessary check by @petreze in #1429 +- Fix inaccurate cost calculation by @petreze in #1430 +- Fix/update mirror endpoints #1448 +- Add delete nft allowances and add delegate spender functionality by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1452 + +**Full Changelog**: https://github.com/hashgraph/hedera-sdk-js/compare/v2.19.2...v2.20.0 + ## v2.19.2 ## What's Changed -* Return dependabot dependency checker by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1361 -* Release/cryptography v1.4.2 by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1366 -* Fix web proxy by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1395 -* Fix `PublicKey.fromString(newAccountPublicKey.toStringDer());` +- Return dependabot dependency checker by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1361 +- Release/cryptography v1.4.2 by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1366 +- Fix web proxy by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1395 +- Fix `PublicKey.fromString(newAccountPublicKey.toStringDer());` ## v2.19.1 ## What's Changed -* KeyList now handles single key properly as first parameter by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1348 -* Fix typo in deprecation suggestion by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1352 -* Update contribution guide by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1353 -* Add max execution time setter for NodeChannel GRPC by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1354 -* Update the addressbook update to be 24 hours by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1359 +- KeyList now handles single key properly as first parameter by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1348 +- Fix typo in deprecation suggestion by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1352 +- Update contribution guide by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1353 +- Add max execution time setter for NodeChannel GRPC by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1354 +- Update the addressbook update to be 24 hours by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1359 ## v2.19.0 ## What's Changed -* Update the Mainnet mirror node and add integration test by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1327 -* Bug/1326 mirror network update by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1328 -* Added getters and deprecated old ones by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1329 -* Integration test workflow by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1330 -* Added proxies for different networks by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1331 -* Аdded NFKD normalization for mnemonic passphrase by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1335 -* Change param of getNftInfo from allowanceSpenderAccountId to spenderId by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1337 -* Fix for optional param of transaction range by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1339 + +- Update the Mainnet mirror node and add integration test by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1327 +- Bug/1326 mirror network update by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1328 +- Added getters and deprecated old ones by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1329 +- Integration test workflow by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1330 +- Added proxies for different networks by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1331 +- Аdded NFKD normalization for mnemonic passphrase by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1335 +- Change param of getNftInfo from allowanceSpenderAccountId to spenderId by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1337 +- Fix for optional param of transaction range by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1339 ## v2.18.6 ## What's Changed -* Fix some of the Github workflows by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1311 -* Bug/unhealthy node by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1321 + +- Fix some of the Github workflows by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1311 +- Bug/unhealthy node by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1321 ## v2.18.5 ## What's Changed -* Throw timeout error and do not make the node unhealthy by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1298 -* Refactor the HIP to point to testnet by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1303 -* Fix for fromBytes to return the range in PrngTransaction by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1302 -* Fix HIP-573 example by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1300 + +- Throw timeout error and do not make the node unhealthy by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1298 +- Refactor the HIP to point to testnet by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1303 +- Fix for fromBytes to return the range in PrngTransaction by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1302 +- Fix HIP-573 example by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1300 ## v2.18.4 ## What's Changed -* Example/hip 573 by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1292 -* Example/hip 564 by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1285 -* Example/hip 542 by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1293 -* bug: fix and improve taskfiles workflow by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1283 -* Fix the task test:release command by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1296 -* Fix the offset for uint24 & int24 datatypes in contract functions params by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1295 + +- Example/hip 573 by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1292 +- Example/hip 564 by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1285 +- Example/hip 542 by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1293 +- bug: fix and improve taskfiles workflow by @petreze in https://github.com/hashgraph/hedera-sdk-js/pull/1283 +- Fix the task test:release command by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1296 +- Fix the offset for uint24 & int24 datatypes in contract functions params by @ochikov in https://github.com/hashgraph/hedera-sdk-js/pull/1295 ## v2.19.0-beta.1 ### Added - * `CustomFee.allCollectorsAreExempt` +- `CustomFee.allCollectorsAreExempt` ## v2.18.3 ### Added - * `PrecheckStatusError.contractFunctionResult` - * `TransactionReceiptQuery.[set|get]ValidateStatus()` - * `TransactionRecrodQuery.[set|get]ValidateReceiptStatus()` +- `PrecheckStatusError.contractFunctionResult` +- `TransactionReceiptQuery.[set|get]ValidateStatus()` +- `TransactionRecrodQuery.[set|get]ValidateReceiptStatus()` ### Fixed - * `WebClient` and `NativeClient` do not schedule network updates +- `WebClient` and `NativeClient` do not schedule network updates ## v2.18.2 ### Added - * `TransactionId.getReceipt()` - * `TransactionId.getRecord()` - * `AccountCreateTransaction.[set|get]Alias[Key|EvmAddress]()` - * `ContractCreateFlow.[set|get]MaxChunks()` - * Support for automatically updating networks - * `Client.[set|get]NetworkUpdatePeriod()` - * `Client` constructor supports `scheduleNetworkUpdate` to disable auto updates - * Support for `local-node` as one of the networks +- `TransactionId.getReceipt()` +- `TransactionId.getRecord()` +- `AccountCreateTransaction.[set|get]Alias[Key|EvmAddress]()` +- `ContractCreateFlow.[set|get]MaxChunks()` +- Support for automatically updating networks +- `Client.[set|get]NetworkUpdatePeriod()` +- `Client` constructor supports `scheduleNetworkUpdate` to disable auto updates +- Support for `local-node` as one of the networks ### Fixed - * `ContractCreateFlow.executeWithSigner()` - * `PublicKey.fromString()` for ECDSA keys - * `WebChannel` not checking headers before decoding body +- `ContractCreateFlow.executeWithSigner()` +- `PublicKey.fromString()` for ECDSA keys +- `WebChannel` not checking headers before decoding body ## v2.18.1 ### Fixed - * `TransferTransaction` incorrectly merging FT and NFT tranfers - * `ContractCreateFlow.execute()` not using keys provided in `.sign()` - * `PublicKey.equals()` +- `TransferTransaction` incorrectly merging FT and NFT tranfers +- `ContractCreateFlow.execute()` not using keys provided in `.sign()` +- `PublicKey.equals()` ## v2.18.0 ### Added - * `Mnemonic.to[Ed25519|Ecdsa]PrivateKey()` +- `Mnemonic.to[Ed25519|Ecdsa]PrivateKey()` ### Deprecated - * `Mnemonic.toPrivateKey()` - Use `Mnemonic.to[Ed25519|Ecdsa]PrivateKey()` +- `Mnemonic.toPrivateKey()` - Use `Mnemonic.to[Ed25519|Ecdsa]PrivateKey()` ### Fixed - * #1188 - Undeprecate `*ContractId.fromSolidityAddress()` +- #1188 - Undeprecate `*ContractId.fromSolidityAddress()` ## v2.17.3 ### Fixed - * `Query.queryPayment`, `Query.maxQueryPayment`, and `Client.maxQueryPayment` interactions - * Remove making empty requests to `grpc.myhbarwallet.com` to calculate time drift +- `Query.queryPayment`, `Query.maxQueryPayment`, and `Client.maxQueryPayment` interactions +- Remove making empty requests to `grpc.myhbarwallet.com` to calculate time drift ### Added - * Expose setters/getters for `Cache` to allow users to set their own calculated values +- Expose setters/getters for `Cache` to allow users to set their own calculated values ## v2.17.2 ### Fixed - * `TokenUpdateTransaction.pauseKey` not being serialized into protobuf +- `TokenUpdateTransaction.pauseKey` not being serialized into protobuf ## v2.17.1 ### Added - * `TokenNftInfo.allowanceSpenderAccountId` - * `ContractCreateFlow.sign[With]()` +- `TokenNftInfo.allowanceSpenderAccountId` +- `ContractCreateFlow.sign[With]()` ### Fixed - * `FileAppendTransaction` chunk size should default to 4096 - * `ContractFunctionResult.gas` can be `-1` when `null` in protobufs: #1208 - * `FileAppendTransaction.setTransactionId()` not locking the transaction ID list - * `TopicMessageSubmitTransaction.setTransactionId()` not locking the transaction ID list +- `FileAppendTransaction` chunk size should default to 4096 +- `ContractFunctionResult.gas` can be `-1` when `null` in protobufs: #1208 +- `FileAppendTransaction.setTransactionId()` not locking the transaction ID list +- `TopicMessageSubmitTransaction.setTransactionId()` not locking the transaction ID list ### Deprecated - * `AccountBalance.tokens` - Use the mirror node API https://docs.hedera.com/guides/docs/mirror-node-api/rest-api#api-v1-accounts instead - * `AccountBalance.tokenDecimals` - Use same API as above +- `AccountBalance.tokens` - Use the mirror node API https://docs.hedera.com/guides/docs/mirror-node-api/rest-api#api-v1-accounts instead +- `AccountBalance.tokenDecimals` - Use same API as above ## v2.17.0 ### Added - * `PrngThansaction` - * `TransactionRecord.prngBytes` - * `TransactionRecord.prngNumber` +- `PrngThansaction` +- `TransactionRecord.prngBytes` +- `TransactionRecord.prngNumber` ### Deprecated - * `ContractFunctionResult.stateChanges` - Use mirror node for contract traceability instead - * `ContractStateChanges` - * `StorageChange` +- `ContractFunctionResult.stateChanges` - Use mirror node for contract traceability instead +- `ContractStateChanges` +- `StorageChange` ## v2.16.6 ### Added - * `ContractCreateTransaction.autoRenewAccountId` - * `ContractUpdateTransaction.autoRenewAccountId` +- `ContractCreateTransaction.autoRenewAccountId` +- `ContractUpdateTransaction.autoRenewAccountId` ## v2.17.0-beta.1 ### Added - * `PrngThansaction` - * `TransactionRecord.prngBytes` - * `TransactionRecord.prngNumber` +- `PrngThansaction` +- `TransactionRecord.prngBytes` +- `TransactionRecord.prngNumber` ## v2.16.5 ### Fixed - * `EthereumFlow` contract creation should hex encode bytes +- `EthereumFlow` contract creation should hex encode bytes ## v2.16.4 ### Fixed - * Time syncing should not continue if `response.headers.date` is NaN - * Time drift should use a POST request with content type set correctly - * Transaction ID generation should no longer fail in browsers +- Time syncing should not continue if `response.headers.date` is NaN +- Time drift should use a POST request with content type set correctly +- Transaction ID generation should no longer fail in browsers ## v2.16.4-beta.3 ### Fixed - * Time syncing should not continue if `response.headers.date` is NaN +- Time syncing should not continue if `response.headers.date` is NaN ## v2.16.4-beta.2 ### Fixed - * Time drift should use a POST request with content type set correctly +- Time drift should use a POST request with content type set correctly ## v2.16.4-beta.1 ### Fixed - * Time drift should use a HEAD request to avoid issues with content type +- Time drift should use a HEAD request to avoid issues with content type ## v2.16.3 ### Fixed - * Implement `AccountAllowanceApproveTransaction.tokenNftApprovals` - * Implement `AccountAllowanceDeleteTransaction.tokenNftAllowanceDeletions` +- Implement `AccountAllowanceApproveTransaction.tokenNftApprovals` +- Implement `AccountAllowanceDeleteTransaction.tokenNftAllowanceDeletions` ## v2.16.2 ### Fixed - * `TokenNftAllowance` to/from protobuf should not assume `spenderAccountId` is set - * Time drift sync should use myhbarwallet to prevent CORS issues +- `TokenNftAllowance` to/from protobuf should not assume `spenderAccountId` is set +- Time drift sync should use myhbarwallet to prevent CORS issues ## v2.16.1 ### Fixed - * Syncing time drift should use https://google.com +- Syncing time drift should use https://google.com ## v2.16.0 ### Added - * `StakingInfo` - * `AccountCreateTransaction.stakedAccountId` - * `AccountCreateTransaction.stakedNodeId` - * `AccountCreateTransaction.declineStakingReward` - * `ContractCreateTransaction.stakedAccountId` - * `ContractCreateTransaction.stakedNodeId` - * `ContractCreateTransaction.declineStakingReward` - * `AccountUpdateTransaction.stakedAccountId` - * `AccountUpdateTransaction.stakedNodeId` - * `AccountUpdateTransaction.declineStakingReward` - * `ContractUpdateTransaction.stakedAccountId` - * `ContractUpdateTransaction.stakedNodeId` - * `ContractUpdateTransaction.declineStakingReward` - * `TransactionRecord.paidStakingRewards` - * `ScheduleCreateTransaction.expirationTime` - * `ScheduleCreateTransaction.waitForExpiry` - * Variants to `FeeDataType` - * `TopicMessage.initialTransactionId` +- `StakingInfo` +- `AccountCreateTransaction.stakedAccountId` +- `AccountCreateTransaction.stakedNodeId` +- `AccountCreateTransaction.declineStakingReward` +- `ContractCreateTransaction.stakedAccountId` +- `ContractCreateTransaction.stakedNodeId` +- `ContractCreateTransaction.declineStakingReward` +- `AccountUpdateTransaction.stakedAccountId` +- `AccountUpdateTransaction.stakedNodeId` +- `AccountUpdateTransaction.declineStakingReward` +- `ContractUpdateTransaction.stakedAccountId` +- `ContractUpdateTransaction.stakedNodeId` +- `ContractUpdateTransaction.declineStakingReward` +- `TransactionRecord.paidStakingRewards` +- `ScheduleCreateTransaction.expirationTime` +- `ScheduleCreateTransaction.waitForExpiry` +- Variants to `FeeDataType` +- `TopicMessage.initialTransactionId` ### Fixed - * `TransactionRecord.[to|from]Bytes()` should round trip correclty +- `TransactionRecord.[to|from]Bytes()` should round trip correclty ## v2.16.0-beta.1 ### Added - * `StakingInfo` - * `AccountCreateTransaction.stakedAccountId` - * `AccountCreateTransaction.stakedNodeId` - * `AccountCreateTransaction.declineStakingReward` - * `ContractCreateTransaction.stakedAccountId` - * `ContractCreateTransaction.stakedNodeId` - * `ContractCreateTransaction.declineStakingReward` - * `AccountUpdateTransaction.stakedAccountId` - * `AccountUpdateTransaction.stakedNodeId` - * `AccountUpdateTransaction.declineStakingReward` - * `ContractUpdateTransaction.stakedAccountId` - * `ContractUpdateTransaction.stakedNodeId` - * `ContractUpdateTransaction.declineStakingReward` - * `TransactionRecord.paidStakingRewards` - * `ScheduleCreateTransaction.expirationTime` - * `ScheduleCreateTransaction.waitForExpiry` +- `StakingInfo` +- `AccountCreateTransaction.stakedAccountId` +- `AccountCreateTransaction.stakedNodeId` +- `AccountCreateTransaction.declineStakingReward` +- `ContractCreateTransaction.stakedAccountId` +- `ContractCreateTransaction.stakedNodeId` +- `ContractCreateTransaction.declineStakingReward` +- `AccountUpdateTransaction.stakedAccountId` +- `AccountUpdateTransaction.stakedNodeId` +- `AccountUpdateTransaction.declineStakingReward` +- `ContractUpdateTransaction.stakedAccountId` +- `ContractUpdateTransaction.stakedNodeId` +- `ContractUpdateTransaction.declineStakingReward` +- `TransactionRecord.paidStakingRewards` +- `ScheduleCreateTransaction.expirationTime` +- `ScheduleCreateTransaction.waitForExpiry` ## v2.15.0 ### Added - * `EthereumFlow` - * `EthereumTransactionData` - * `EthereumTransactionDataLegacy` - * `EthereumTransactionDataEip1559` - * `Signer.getAccountKey()` - Signature providers _should_ be implementing this method, but - it was added in a none-breaking change way so old signer provider implementations won't - break when updating to the latest JS SDK version - * `ContractCreateFlow.executeWithSigner()` - Execute a flow using a signer - * `AccountInfoFlow.verify[Signature|Transaction]WithSigner()` - Execute a flow using a signer - * A third party time source will be used for transaction ID generation when possible. +- `EthereumFlow` +- `EthereumTransactionData` +- `EthereumTransactionDataLegacy` +- `EthereumTransactionDataEip1559` +- `Signer.getAccountKey()` - Signature providers _should_ be implementing this method, but + it was added in a none-breaking change way so old signer provider implementations won't + break when updating to the latest JS SDK version +- `ContractCreateFlow.executeWithSigner()` - Execute a flow using a signer +- `AccountInfoFlow.verify[Signature|Transaction]WithSigner()` - Execute a flow using a signer +- A third party time source will be used for transaction ID generation when possible. ### Deprecated - * `EthereumTransaction.[set|get]CallData()` - Use `EthereumTransaction.[set|get]CallDataFileId()` instead - * `EthereumTransaction.[set|get]MaxGasAllowance()` - Use `EthereumTransaction.[set|get]MaxGasAllowanceHbar()` instead +- `EthereumTransaction.[set|get]CallData()` - Use `EthereumTransaction.[set|get]CallDataFileId()` instead +- `EthereumTransaction.[set|get]MaxGasAllowance()` - Use `EthereumTransaction.[set|get]MaxGasAllowanceHbar()` instead ## v2.14.2 ### Added - * Exported `RequestType` +- Exported `RequestType` ### Fixed - * `RequestType` missing codes +- `RequestType` missing codes ## v2.14.1 ### Added - * Exported `FeeComponents` - * Exported `FeeData` - * Exported `FeeDataType` - * Exported `FeeSchedule` - * Exported `FeeSchedules` - * Exported `TransactionFeeSchedule` +- Exported `FeeComponents` +- Exported `FeeData` +- Exported `FeeDataType` +- Exported `FeeSchedule` +- Exported `FeeSchedules` +- Exported `TransactionFeeSchedule` ## v2.14.0 ### Added - * `AccountId.aliasEvmAddress` - * `ContractCreateTransaction.[get|set]MaxAutomaticTokenAssociations()` - * `ContractCreateTransaction.[get|set]Bytecode()` - * `ContractUpdateTransaction.[get|set]MaxAutomaticTokenAssociations()` - * `ContractCreateFlow.[get|set]MaxAutomaticTokenAssociations()` - * `AccountInfo.ethereumNonce` - * `ContractCallResult.senderAccountId` - * `ContractCallQuery.[get|set]SenderAccountId()` - * `TransactionRecord.ethereumHash` - * `EthereumTransaction` - * `TransactionResponse.get[Receipt|Record]Query()` - * `[Wallet|Signer|Provider].sendRequest()` -> `[Wallet|Signer|Provider].call()` - * `[Wallet|Signer].[sign|populate|check]Transaction()` are now generic over the parameter - * `Wallet.checkTransaction` should not error if the `Transaction.transactionId` is `null` - * More status codes to `Status` +- `AccountId.aliasEvmAddress` +- `ContractCreateTransaction.[get|set]MaxAutomaticTokenAssociations()` +- `ContractCreateTransaction.[get|set]Bytecode()` +- `ContractUpdateTransaction.[get|set]MaxAutomaticTokenAssociations()` +- `ContractCreateFlow.[get|set]MaxAutomaticTokenAssociations()` +- `AccountInfo.ethereumNonce` +- `ContractCallResult.senderAccountId` +- `ContractCallQuery.[get|set]SenderAccountId()` +- `TransactionRecord.ethereumHash` +- `EthereumTransaction` +- `TransactionResponse.get[Receipt|Record]Query()` +- `[Wallet|Signer|Provider].sendRequest()` -> `[Wallet|Signer|Provider].call()` +- `[Wallet|Signer].[sign|populate|check]Transaction()` are now generic over the parameter +- `Wallet.checkTransaction` should not error if the `Transaction.transactionId` is `null` +- More status codes to `Status` ### Fixed - * Bumped `@hashgraph/proto` version to correctly support account allowances - * `TransactionId.transactionId` accessor should not error if there is no transaction ID set and - instead should return a nullable `TransactionId` - * `ContractFunctionParameters.addBytes()` where the byte length is a factor of 32 and greater than 32 - * `[Web|Native]Channel` should correctly propagate the error from `fetch()` +- Bumped `@hashgraph/proto` version to correctly support account allowances +- `TransactionId.transactionId` accessor should not error if there is no transaction ID set and + instead should return a nullable `TransactionId` +- `ContractFunctionParameters.addBytes()` where the byte length is a factor of 32 and greater than 32 +- `[Web|Native]Channel` should correctly propagate the error from `fetch()` ## v2.14.0-beta.2 ### Added - * `ContractEvmTransaction` +- `ContractEvmTransaction` ## v2.14.0-beta.1 ### Added - * More status codes to `Status` +- More status codes to `Status` ### Changed - * `[Wallet|Signer|Provider].sendRequest()` -> `[Wallet|Signer|Provider].call()` - * `[Wallet|Signer].[sign|populate|check]Transaction()` are now generic over the parameter - * `Wallet.checkTransaction` should not error if the `Transaction.transactionId` is `null` +- `[Wallet|Signer|Provider].sendRequest()` -> `[Wallet|Signer|Provider].call()` +- `[Wallet|Signer].[sign|populate|check]Transaction()` are now generic over the parameter +- `Wallet.checkTransaction` should not error if the `Transaction.transactionId` is `null` ### Fixed - * Bumped `@hashgraph/proto` version to correctly support account allowances - * `TransactionId.transactionId` accessor should not error if there is no transaction ID set and - instead should return a nullable `TransactionId` - * `ContractFunctionParameters.addBytes()` where the byte length is a factor of 32 and greater than 32 - * `[Web|Native]Channel` should correctly propagate the error from `fetch()` +- Bumped `@hashgraph/proto` version to correctly support account allowances +- `TransactionId.transactionId` accessor should not error if there is no transaction ID set and + instead should return a nullable `TransactionId` +- `ContractFunctionParameters.addBytes()` where the byte length is a factor of 32 and greater than 32 +- `[Web|Native]Channel` should correctly propagate the error from `fetch()` ## v2.13.1 ### Fixed - * `AccountId.clone()` should clone the `aliasKey` +- `AccountId.clone()` should clone the `aliasKey` ## v2.13.0 -### Added +### Added - * `ContractFunctionResult.[gas|amount|functionParameters]` - * `AccountAllowanceDeleteTransaction` - * `Wallet.createRandom[ED25519|ECDSA]()` +- `ContractFunctionResult.[gas|amount|functionParameters]` +- `AccountAllowanceDeleteTransaction` +- `Wallet.createRandom[ED25519|ECDSA]()` ### Fixed - * `WebChannel` and `NativeChannel` using `HashgraphProto.proto` instead of `proto` in the URL - * `TransactionReceiptQuery`'s error should contain the transaction set on the request instead - of the payment transaction ID - * `Query.maxQueryPayment` should be used before `Client.maxQueryPayment` - * request timeout check being reversed +- `WebChannel` and `NativeChannel` using `HashgraphProto.proto` instead of `proto` in the URL +- `TransactionReceiptQuery`'s error should contain the transaction set on the request instead + of the payment transaction ID +- `Query.maxQueryPayment` should be used before `Client.maxQueryPayment` +- request timeout check being reversed ### Changed - * Updated `Signer` and `Provider` to be interfaces instead of classes +- Updated `Signer` and `Provider` to be interfaces instead of classes ### Deprecated - * `AccountAllowanceAdjustTransaction` +- `AccountAllowanceAdjustTransaction` ### Removed - * `LocalWallet` - Use `Wallet` instead +- `LocalWallet` - Use `Wallet` instead ## v2.13.0-beta.1 ### Fixed - - * `TopicUpdateTransaction` should be able to call [get|set]ExpirationTime(). - * `Status` should contain a return code for 314. -### Added +- `TopicUpdateTransaction` should be able to call [get|set]ExpirationTime(). +- `Status` should contain a return code for 314. + +### Added - * `ContractFunctionResult.[gas|amount|functionParameters]` - * `AccountAllowanceDeleteTransaction` +- `ContractFunctionResult.[gas|amount|functionParameters]` +- `AccountAllowanceDeleteTransaction` ## v2.12.1 ### Fixed - * Only check for logging environment variables inside `index.js` - * Update `Exectuable`, `Query`, and `CostQuery` to correctly set `nodeAccountIds` - * Make suer `Query` saves the operator from the client to be used when building - new payment transactions +- Only check for logging environment variables inside `index.js` +- Update `Exectuable`, `Query`, and `CostQuery` to correctly set `nodeAccountIds` +- Make suer `Query` saves the operator from the client to be used when building + new payment transactions ## v2.12.0 ### Added - * `AccountInfoFlow.verify[Signature|Transaction]()` - * `Client.[set|get]NodeMinReadmitPeriod()` - * Support for using any node from the entire network upon execution - if node account IDs have no been locked for the request. - * Support for all integer widths for `ContractFunction[Result|Selector|Params]` - * `AccountAllowanceApproveTransaction.approve[Hbar|Token|TokenNft]Allowance()` - * `AccountAllowanceAdjustTransaction.[grant|revoke][Hbar|Token|TokenNft]Allowance()` - * `AccountAllowanceAdjustTransaction.[grant|revoke]TokenNftAllowanceAllSerials()` - * `TransactionRecord.[hbar|token|tokenNft]AllowanceAdjustments` - * `TransferTransaction.addApproved[Hbar|Token|Nft]Transfer()` +- `AccountInfoFlow.verify[Signature|Transaction]()` +- `Client.[set|get]NodeMinReadmitPeriod()` +- Support for using any node from the entire network upon execution + if node account IDs have no been locked for the request. +- Support for all integer widths for `ContractFunction[Result|Selector|Params]` +- `AccountAllowanceApproveTransaction.approve[Hbar|Token|TokenNft]Allowance()` +- `AccountAllowanceAdjustTransaction.[grant|revoke][Hbar|Token|TokenNft]Allowance()` +- `AccountAllowanceAdjustTransaction.[grant|revoke]TokenNftAllowanceAllSerials()` +- `TransactionRecord.[hbar|token|tokenNft]AllowanceAdjustments` +- `TransferTransaction.addApproved[Hbar|Token|Nft]Transfer()` ### Deprecated - * `AccountAllowanceApproveTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `approve*Allowance()` instead. - * `AccountAllowanceAdjustTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `[grant|revoke]*Allowance()` instead. - * `TransferTransaction.set[Hbar|Token|Nft]TransferApproval()`, use `addApproved*Transfer()` instead. +- `AccountAllowanceApproveTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `approve*Allowance()` instead. +- `AccountAllowanceAdjustTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `[grant|revoke]*Allowance()` instead. +- `TransferTransaction.set[Hbar|Token|Nft]TransferApproval()`, use `addApproved*Transfer()` instead. ### Changed - * Network behavior to follow a more standard approach (remove the sorting we - used to do). +- Network behavior to follow a more standard approach (remove the sorting we + used to do). ### Fixed - * Ledger ID checksums - * `Transaction.fromBytes()` should validate all the transaction bodies are the same - * `ExchangeRate._[from|to]Protobuf()` should correctly decode `expirationTime` - * Mark `expo` as a optional peer dependency - * `SubscriptionHandle` should be exported - * `TransferTransaction` transfers merging +- Ledger ID checksums +- `Transaction.fromBytes()` should validate all the transaction bodies are the same +- `ExchangeRate._[from|to]Protobuf()` should correctly decode `expirationTime` +- Mark `expo` as a optional peer dependency +- `SubscriptionHandle` should be exported +- `TransferTransaction` transfers merging ## v2.11.3 ### Fixed - * Scheduled transactions should use the default transaction fee if a fee was not - explicitly set +- Scheduled transactions should use the default transaction fee if a fee was not + explicitly set ## v2.11.2 ### Added - * `TransactionRecord.[hbar|token|tokenNft]AllowanceAdjustments` - * `TransferTransaction.addApproved[Hbar|Token|Nft]Transfer()` +- `TransactionRecord.[hbar|token|tokenNft]AllowanceAdjustments` +- `TransferTransaction.addApproved[Hbar|Token|Nft]Transfer()` ## v2.11.1 ### Added - * `AccountAllowanceApproveTransaction.approve[Hbar|Token|TokenNft]Allowance()` - * `AccountAllowanceAdjustTransaction.[grant|revoke][Hbar|Token|TokenNft]Allowance()` - * `AccountAllowanceAdjustTransaction.[grant|revoke]TokenNftAllowanceAllSerials()` +- `AccountAllowanceApproveTransaction.approve[Hbar|Token|TokenNft]Allowance()` +- `AccountAllowanceAdjustTransaction.[grant|revoke][Hbar|Token|TokenNft]Allowance()` +- `AccountAllowanceAdjustTransaction.[grant|revoke]TokenNftAllowanceAllSerials()` ## v2.12.0-beta.1 ### Added - * `AccountInfoFlow.verify[Signature|Transaction]()` - * `Client.[set|get]NodeMinReadmitPeriod()` - * Support for using any node from the entire network upon execution - if node account IDs have no been locked for the request. - * Support for all integer widths for `ContractFunction[Result|Selector|Params]` - * `AccountAllowanceApproveTransaction.approve[Hbar|Token|TokenNft]Allowance()` - * `AccountAllowanceAdjustTransaction.[grant|revoke][Hbar|Token|TokenNft]Allowance()` - * `AccountAllowanceAdjustTransaction.[grant|revoke]TokenNftAllowanceAllSerials()` - * `TransactionRecord.[hbar|token|tokenNft]AllowanceAdjustments` - * `TransferTransaction.addApproved[Hbar|Token|Nft]Transfer()` - * Ledger ID checksums - * `Transaction.fromBytes()` should validate all the transaction bodies are the same +- `AccountInfoFlow.verify[Signature|Transaction]()` +- `Client.[set|get]NodeMinReadmitPeriod()` +- Support for using any node from the entire network upon execution + if node account IDs have no been locked for the request. +- Support for all integer widths for `ContractFunction[Result|Selector|Params]` +- `AccountAllowanceApproveTransaction.approve[Hbar|Token|TokenNft]Allowance()` +- `AccountAllowanceAdjustTransaction.[grant|revoke][Hbar|Token|TokenNft]Allowance()` +- `AccountAllowanceAdjustTransaction.[grant|revoke]TokenNftAllowanceAllSerials()` +- `TransactionRecord.[hbar|token|tokenNft]AllowanceAdjustments` +- `TransferTransaction.addApproved[Hbar|Token|Nft]Transfer()` +- Ledger ID checksums +- `Transaction.fromBytes()` should validate all the transaction bodies are the same ### Deprecated - * `AccountAllowanceApproveTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `approve*Allowance()` instead. - * `AccountAllowanceAdjustTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `[grant|revoke]*Allowance()` instead. - * `TransferTransaction.set[Hbar|Token|Nft]TransferApproval()`, use `addApproved*Transfer()` instead. +- `AccountAllowanceApproveTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `approve*Allowance()` instead. +- `AccountAllowanceAdjustTransaction.add[Hbar|Token|TokenNft]Allowance[WithOwner]()`, use `[grant|revoke]*Allowance()` instead. +- `TransferTransaction.set[Hbar|Token|Nft]TransferApproval()`, use `addApproved*Transfer()` instead. ### Changed - * Network behavior to follow a more standard approach (remove the sorting we - used to do). +- Network behavior to follow a more standard approach (remove the sorting we + used to do). ### Fixed - * Ledger ID checksums - * `Transaction.fromBytes()` should validate all the transaction bodies are the same - * `ExchangeRate._[from|to]Protobuf()` should correctly decode `expirationTime` - * Mark `expo` as a optional peer dependency +- Ledger ID checksums +- `Transaction.fromBytes()` should validate all the transaction bodies are the same +- `ExchangeRate._[from|to]Protobuf()` should correctly decode `expirationTime` +- Mark `expo` as a optional peer dependency ### Added @@ -531,594 +559,594 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - * `LocalWallet` - * `LocalProvider` - * `Provider` - * `Signer` - * `Wallet` - * `SignerSignature` - * Verbose logging using `js-logger` - * `Client.setRequestTimeout()` +- `LocalWallet` +- `LocalProvider` +- `Provider` +- `Signer` +- `Wallet` +- `SignerSignature` +- Verbose logging using `js-logger` +- `Client.setRequestTimeout()` ### Fixed - * TLS for mirror nodes - * Transactions should have an appropriate default (copied from Java SDK) - * Min/max backoff for nodes should start at 8s to 60s - * The current backoff for nodes should be used when sorting inside of network - meaning nodes with a smaller current backoff will be prioritized - * Chunked transactions (`FileAppendTransaction` and `TopicMessageSubmitTransaction`) should - use the correct transation ID per transaction - * Transaction removing signatures when calling `Transaction.[toBytes|getTransactionHash]()` +- TLS for mirror nodes +- Transactions should have an appropriate default (copied from Java SDK) +- Min/max backoff for nodes should start at 8s to 60s +- The current backoff for nodes should be used when sorting inside of network + meaning nodes with a smaller current backoff will be prioritized +- Chunked transactions (`FileAppendTransaction` and `TopicMessageSubmitTransaction`) should + use the correct transation ID per transaction +- Transaction removing signatures when calling `Transaction.[toBytes|getTransactionHash]()` ## v2.11.0-beta.1 ### Added - * `LocalWallet` - * `LocalProvider` - * `Provider` - * `Signer` - * `Wallet` - * `SignerSignature` - * Verbose logging using `js-logger` - * `Client.setRequestTimeout()` +- `LocalWallet` +- `LocalProvider` +- `Provider` +- `Signer` +- `Wallet` +- `SignerSignature` +- Verbose logging using `js-logger` +- `Client.setRequestTimeout()` ### Fixed - * TLS for mirror nodes - * Transactions should have an appropriate default (copied from Java SDK) - * Min/max backoff for nodes should start at 8s to 60s - * The current backoff for nodes should be used when sorting inside of network - meaning nodes with a smaller current backoff will be prioritized - * Chunked transactions (`FileAppendTransaction` and `TopicMessageSubmitTransaction`) should - use the correct transation ID per transaction - * Transaction removing signatures when calling `Transaction.[toBytes|getTransactionHash]()` +- TLS for mirror nodes +- Transactions should have an appropriate default (copied from Java SDK) +- Min/max backoff for nodes should start at 8s to 60s +- The current backoff for nodes should be used when sorting inside of network + meaning nodes with a smaller current backoff will be prioritized +- Chunked transactions (`FileAppendTransaction` and `TopicMessageSubmitTransaction`) should + use the correct transation ID per transaction +- Transaction removing signatures when calling `Transaction.[toBytes|getTransactionHash]()` ## v2.10.1 ### Fixes - * `NativeClient` IPs should have a port +- `NativeClient` IPs should have a port ## v2.10.0 ### Added - * `AddressBookQuery` - * Status codes - * `*[Transaction|Query].setGrpcDeadline()` - * `*Allowance.ownerAccountId` +- `AddressBookQuery` +- Status codes +- `*[Transaction|Query].setGrpcDeadline()` +- `*Allowance.ownerAccountId` ### Fixed - * Mirror network incorrectly using `433` for TLS instead of `443` - * `TransactionReceipt` protobuf encoding - * `ContractId.fromString()` +- Mirror network incorrectly using `433` for TLS instead of `443` +- `TransactionReceipt` protobuf encoding +- `ContractId.fromString()` ## v2.10.0-beta.1 ### Added - * `AddressBookQuery` - * Status codes - * `*[Transaction|Query].setGrpcDeadline()` - * `*Allowance.ownerAccountId` +- `AddressBookQuery` +- Status codes +- `*[Transaction|Query].setGrpcDeadline()` +- `*Allowance.ownerAccountId` ## v2.9.1 ### Fixed - * Mirror network incorrectly using `433` for TLS instead of `443` - * `TransactionReceipt` protobuf encoding - * `ContractId.fromString()` +- Mirror network incorrectly using `433` for TLS instead of `443` +- `TransactionReceipt` protobuf encoding +- `ContractId.fromString()` ## v2.10.0-beta.1 ### Added - * `AddressBookQuery` - * Status codes - * `*[Transaction|Query].setGrpcDeadline()` - * `*Allowance.ownerAccountId` +- `AddressBookQuery` +- Status codes +- `*[Transaction|Query].setGrpcDeadline()` +- `*Allowance.ownerAccountId` ### Fixed - * Mirror network incorrectly using `433` for TLS instead of `443` - * `TransactionReceipt` protobuf encoding - * `ContractId.fromString()` +- Mirror network incorrectly using `433` for TLS instead of `443` +- `TransactionReceipt` protobuf encoding +- `ContractId.fromString()` ## v2.9.0 ### Added - * `ContractId.fromEvmAddress()` - * `ContractFunctionResult.stateChanges` - * `ContractFunctionResult.evmAddress` - * `ContractStateChange` - * `StorageChange` - * `[FileAppend|TopicMessageSubmit]Transaction.[set|get]ChunkSize()`, and changed default chunk size for `FileAppendTransaction` to 2048. - * `AccountAllowance[Adjust|Approve]Transaction` - * `TransactionRecord.tokenTransfersList` +- `ContractId.fromEvmAddress()` +- `ContractFunctionResult.stateChanges` +- `ContractFunctionResult.evmAddress` +- `ContractStateChange` +- `StorageChange` +- `[FileAppend|TopicMessageSubmit]Transaction.[set|get]ChunkSize()`, and changed default chunk size for `FileAppendTransaction` to 2048. +- `AccountAllowance[Adjust|Approve]Transaction` +- `TransactionRecord.tokenTransfersList` ## v2.9.0-beta.1 ### Added - * `ContractId.fromEvmAddress()` - * `ContractFunctionResult.stateChanges` - * `ContractFunctionResult.evmAddress` - * `ContractStateChange` - * `StorageChange` - * `[FileAppend|TopicMessageSubmit]Transaction.[set|get]ChunkSize()`, and changed default chunk size for `FileAppendTransaction` to 2048. - * `AccountAllowance[Adjust|Approve]Transaction` - * `TransactionRecord.tokenTransfersList` - * `AccountAllowance[Adjust|Approve]Transaction` - * `AccountInfo.[hbar|token|tokenNft]Allowances` - * `[Hbar|Token|TokenNft]Allowance` - * `[Hbar|Token|TokenNft]Allowance` - * `TransferTransaction.set[Hbar|Token|TokenNft]TransferApproval()` +- `ContractId.fromEvmAddress()` +- `ContractFunctionResult.stateChanges` +- `ContractFunctionResult.evmAddress` +- `ContractStateChange` +- `StorageChange` +- `[FileAppend|TopicMessageSubmit]Transaction.[set|get]ChunkSize()`, and changed default chunk size for `FileAppendTransaction` to 2048. +- `AccountAllowance[Adjust|Approve]Transaction` +- `TransactionRecord.tokenTransfersList` +- `AccountAllowance[Adjust|Approve]Transaction` +- `AccountInfo.[hbar|token|tokenNft]Allowances` +- `[Hbar|Token|TokenNft]Allowance` +- `[Hbar|Token|TokenNft]Allowance` +- `TransferTransaction.set[Hbar|Token|TokenNft]TransferApproval()` ## v2.8.0 ### Added - * Support for regenerating transaction IDs on demand if a request - responses with `TRANSACITON_EXPIRED` +- Support for regenerating transaction IDs on demand if a request + responses with `TRANSACITON_EXPIRED` ### Fixed - * `Transaction.sign()` should correctly save public keys and signers when sign on demand is disabled - * `WebClient` failing to be constructed because its network was missing ports +- `Transaction.sign()` should correctly save public keys and signers when sign on demand is disabled +- `WebClient` failing to be constructed because its network was missing ports ## v2.8.0-beta.2 ### Fixed - * `Transaction.sign()` should correctly save public keys and signers when sign on demand is disabled - * `WebClient` failing to be constructed because its network was missing ports +- `Transaction.sign()` should correctly save public keys and signers when sign on demand is disabled +- `WebClient` failing to be constructed because its network was missing ports ## v2.7.1 ### Fixed - * `WebClient` failing to be constructed because its network was missing ports +- `WebClient` failing to be constructed because its network was missing ports ## v2.8.0-beta.1 ### Added - * Support for regenerating transaction IDs on demand if a request - responses with `TRANSACITON_EXPIRED` +- Support for regenerating transaction IDs on demand if a request + responses with `TRANSACITON_EXPIRED` ## v2.7.0 ### Added - * `[Private|Public]Key.toAccountId()` - * `TokenUpdateTransaction.[get|set]PauseKey()` - * `TokenUpdateTransaction.setSupplyKey()` - * Updated `Status` with new response codes - * `AccountId.aliasKey`, including `AccountId.[to|from]String()` support. - * `[PublicKey|PrivateKey].toAccountId()`. - * `aliasKey` fields in `TransactionRecord` and `AccountInfo`. - * `nonce` field in `TransactionId`, including `TransactionId.[set|get]Nonce()` - * `children` fields in `TransactionRecord` and `TransactionReceipt` - * `duplicates` field in `TransactionReceipt` - * `[TransactionReceiptQuery|TransactionRecordQuery].[set|get]IncludeChildren()` - * `TransactionReceiptQuery.[set|get]IncludeDuplicates()` - * New response codes. - * Support for ECDSA SecP256K1 keys. - * `PrivateKey.generate[ED25519|ECDSA]()` - * `[Private|Public]Key.from[Bytes|String][DER|ED25519|ECDSA]()` - * `[Private|Public]Key.to[Bytes|String][Raw|DER]()` +- `[Private|Public]Key.toAccountId()` +- `TokenUpdateTransaction.[get|set]PauseKey()` +- `TokenUpdateTransaction.setSupplyKey()` +- Updated `Status` with new response codes +- `AccountId.aliasKey`, including `AccountId.[to|from]String()` support. +- `[PublicKey|PrivateKey].toAccountId()`. +- `aliasKey` fields in `TransactionRecord` and `AccountInfo`. +- `nonce` field in `TransactionId`, including `TransactionId.[set|get]Nonce()` +- `children` fields in `TransactionRecord` and `TransactionReceipt` +- `duplicates` field in `TransactionReceipt` +- `[TransactionReceiptQuery|TransactionRecordQuery].[set|get]IncludeChildren()` +- `TransactionReceiptQuery.[set|get]IncludeDuplicates()` +- New response codes. +- Support for ECDSA SecP256K1 keys. +- `PrivateKey.generate[ED25519|ECDSA]()` +- `[Private|Public]Key.from[Bytes|String][DER|ED25519|ECDSA]()` +- `[Private|Public]Key.to[Bytes|String][Raw|DER]()` ### Fixed - * Requests should retry on `INTERNAL` consistently - * Signing data which contains bytes larger than a value of 127 - * `[Private|Public]Key.fromBytesEcdsa()` checking for the wrong bytes length +- Requests should retry on `INTERNAL` consistently +- Signing data which contains bytes larger than a value of 127 +- `[Private|Public]Key.fromBytesEcdsa()` checking for the wrong bytes length ### Deprecated - * `TokenUpdateTransaction.setsupplyKey()` - use `setSupplyKey()` instead - * `PrivateKey.generate()`, use `PrivateKey.generate[ED25519|ECDSA]()` instead. +- `TokenUpdateTransaction.setsupplyKey()` - use `setSupplyKey()` instead +- `PrivateKey.generate()`, use `PrivateKey.generate[ED25519|ECDSA]()` instead. ## v2.7.0-beta.4 ### Fixed - * Signing data which contains bytes larger than a value of 127 - * `[Private|Public]Key.fromBytesEcdsa()` checking for the wrong bytes length +- Signing data which contains bytes larger than a value of 127 +- `[Private|Public]Key.fromBytesEcdsa()` checking for the wrong bytes length ## v2.7.0-beta.3 ### Added - * `TokenUpdateTransaction.[get|set]PauseKey()` - * `TokenUpdateTransaction.setSupplyKey()` - * Updated `Status` with new response codes +- `TokenUpdateTransaction.[get|set]PauseKey()` +- `TokenUpdateTransaction.setSupplyKey()` +- Updated `Status` with new response codes ### Deprecated - * `TokenUpdateTransaction.setsupplyKey()` - use `setSupplyKey()` instead +- `TokenUpdateTransaction.setsupplyKey()` - use `setSupplyKey()` instead ## v2.7.0-beta.2 ### Added - * `[Private|Public]Key.toAccountId()` +- `[Private|Public]Key.toAccountId()` ## v2.7.0-beta.1 ### Added - * `AccountId.aliasKey`, including `AccountId.[to|from]String()` support. - * `[PublicKey|PrivateKey].toAccountId()`. - * `aliasKey` fields in `TransactionRecord` and `AccountInfo`. - * `nonce` field in `TransactionId`, including `TransactionId.[set|get]Nonce()` - * `children` fields in `TransactionRecord` and `TransactionReceipt` - * `duplicates` field in `TransactionReceipt` - * `[TransactionReceiptQuery|TransactionRecordQuery].[set|get]IncludeChildren()` - * `TransactionReceiptQuery.[set|get]IncludeDuplicates()` - * New response codes. - * Support for ECDSA SecP256K1 keys. - * `PrivateKey.generate[ED25519|ECDSA]()` - * `[Private|Public]Key.from[Bytes|String][DER|ED25519|ECDSA]()` - * `[Private|Public]Key.to[Bytes|String][Raw|DER]()` +- `AccountId.aliasKey`, including `AccountId.[to|from]String()` support. +- `[PublicKey|PrivateKey].toAccountId()`. +- `aliasKey` fields in `TransactionRecord` and `AccountInfo`. +- `nonce` field in `TransactionId`, including `TransactionId.[set|get]Nonce()` +- `children` fields in `TransactionRecord` and `TransactionReceipt` +- `duplicates` field in `TransactionReceipt` +- `[TransactionReceiptQuery|TransactionRecordQuery].[set|get]IncludeChildren()` +- `TransactionReceiptQuery.[set|get]IncludeDuplicates()` +- New response codes. +- Support for ECDSA SecP256K1 keys. +- `PrivateKey.generate[ED25519|ECDSA]()` +- `[Private|Public]Key.from[Bytes|String][DER|ED25519|ECDSA]()` +- `[Private|Public]Key.to[Bytes|String][Raw|DER]()` ### Deprecated - * `PrivateKey.generate()`, use `PrivateKey.generate[ED25519|ECDSA]()` instead. +- `PrivateKey.generate()`, use `PrivateKey.generate[ED25519|ECDSA]()` instead. ### Fixed - * Requests should retry on `INTERNAL` consistently +- Requests should retry on `INTERNAL` consistently ## v2.6.0 ### Added - * Support for multiple IPs per node - * New smart contract response codes +- Support for multiple IPs per node +- New smart contract response codes ### Fixed - * `TransferTransaction` should deterministically order transfers before submitting transaction +- `TransferTransaction` should deterministically order transfers before submitting transaction ## v2.6.0-beta.1 ## Added - * New smart contract response codes +- New smart contract response codes ## v2.5.0 ### Fixed - * `WebClient` should be able to construct an empty `MirrorNetwork` - * Bad imports while using Common JS +- `WebClient` should be able to construct an empty `MirrorNetwork` +- Bad imports while using Common JS ### Deprecated - * `ContractUpdateTransaction.[set|get]ByteCodeFileId()` - * `ContractCallQuery.[set|get]MaxResultSize()` +- `ContractUpdateTransaction.[set|get]ByteCodeFileId()` +- `ContractCallQuery.[set|get]MaxResultSize()` ## v2.5.0-beta.2 ### Fixed - * Bad imports while using Common JS +- Bad imports while using Common JS ## v2.5.0-beta.1 ### Deprecated - * `ContractUpdateTransaction.[set|get]ByteCodeFileId()` - * `ContractCallQuery.[set|get]MaxResultSize()` +- `ContractUpdateTransaction.[set|get]ByteCodeFileId()` +- `ContractCallQuery.[set|get]MaxResultSize()` ## v2.4.1 ### Fixed - * Bad imports while using Common JS +- Bad imports while using Common JS ## v2.4.0 ### Added - * TLS support - * `Client.[get|set]TransportSecurity()` - Enable/Disable TLS - * `*Id.toSolidityAddress()` - * Support for `number` in all `ContractFunctionParam.add[Uint|Int]*()` methods +- TLS support +- `Client.[get|set]TransportSecurity()` - Enable/Disable TLS +- `*Id.toSolidityAddress()` +- Support for `number` in all `ContractFunctionParam.add[Uint|Int]*()` methods ### Fixed - * `*Id.fromSolidityAddress()` +- `*Id.fromSolidityAddress()` ## v2.3.0 ### Added - * `FreezeType` - * `FreezeTransaction.[get|set]FreezeType()` - * `FreezeTransaction.[get|set]FileId()` - * `FreezeTransaction.[get|set]FileHash()` +- `FreezeType` +- `FreezeTransaction.[get|set]FreezeType()` +- `FreezeTransaction.[get|set]FileId()` +- `FreezeTransaction.[get|set]FileHash()` ### Deprecated - * `FreezeTransaction.[get|set]UpdateFileId()`, use `.[get|set]FileId()` instead. +- `FreezeTransaction.[get|set]UpdateFileId()`, use `.[get|set]FileId()` instead. ## v2.2.0 ### Fixed - * gRPC client not timing out on unresponsive connections +- gRPC client not timing out on unresponsive connections ## v2.2.0-beta.1 ### Added - * Support for HIP-24 (token pausing) - * `TokenInfo.pauseKey` - * `TokenInfo.pauseStatus` - * `TokenCreateTransaction.pauseKey` - * `TokenUpdateTransaction.pauseKey` - * `TokenPauseTransaction` - * `TokenUnpauseTransaction` +- Support for HIP-24 (token pausing) + - `TokenInfo.pauseKey` + - `TokenInfo.pauseStatus` + - `TokenCreateTransaction.pauseKey` + - `TokenUpdateTransaction.pauseKey` + - `TokenPauseTransaction` + - `TokenUnpauseTransaction` ## v2.1.1 ### Fixed - * UTF8 encoding and ecoding in React Native +- UTF8 encoding and ecoding in React Native ## v2.1.0 ### Added - * Support for automatic token associations - * `TransactionRecord.automaticTokenAssociations` - * `AccountInfo.maxAutomaticTokenAssociations` - * `AccountCreateTransaction.maxAutomaticTokenAssociations` - * `AccountUpdateTransaction.maxAutomaticTokenAssociations` - * `TokenRelationship.automaticAssociation` - * `TokenAssociation` +- Support for automatic token associations + - `TransactionRecord.automaticTokenAssociations` + - `AccountInfo.maxAutomaticTokenAssociations` + - `AccountCreateTransaction.maxAutomaticTokenAssociations` + - `AccountUpdateTransaction.maxAutomaticTokenAssociations` + - `TokenRelationship.automaticAssociation` + - `TokenAssociation` ### Fixed - * `TransferTransaction.addHbarTransfer()` was not combining transfers +- `TransferTransaction.addHbarTransfer()` was not combining transfers ## v2.1.0-beta.1 ### Added - * Support for automatic token associations - * `TransactionRecord.automaticTokenAssociations` - * `AccountInfo.maxAutomaticTokenAssociations` - * `AccountCreateTransaction.maxAutomaticTokenAssociations` - * `AccountUpdateTransaction.maxAutomaticTokenAssociations` - * `TokenRelationship.automaticAssociation` - * `TokenAssociation` +- Support for automatic token associations + - `TransactionRecord.automaticTokenAssociations` + - `AccountInfo.maxAutomaticTokenAssociations` + - `AccountCreateTransaction.maxAutomaticTokenAssociations` + - `AccountUpdateTransaction.maxAutomaticTokenAssociations` + - `TokenRelationship.automaticAssociation` + - `TokenAssociation` ## v2.0.30 ### Added - * `TokenNftInfo.toString()` - Stringifies the JSON representation of the current `TokenNftInfo` - * `TokenNftInfo.toJson()` - JSON representation of the current `TokenNftInfo` - * `Timestamp.toString()` - displays as `.`. Use `Timestamp.toDate()` to print differently +- `TokenNftInfo.toString()` - Stringifies the JSON representation of the current `TokenNftInfo` +- `TokenNftInfo.toJson()` - JSON representation of the current `TokenNftInfo` +- `Timestamp.toString()` - displays as `.`. Use `Timestamp.toDate()` to print differently ### Deprecated - * `TokenNftInfoQuery.[set|get]AccountId()` with no replacement - * `TokenNftInfoQuery.[set|get]TokenId()` with no replacement - * `TokenNftInfoQuery.[set|get]Start()` with no replacement - * `TokenNftInfoQuery.[set|get]End()` with no replacement - * `TokenMintTransaction.[add|set]Metadata()` support for string metadata +- `TokenNftInfoQuery.[set|get]AccountId()` with no replacement +- `TokenNftInfoQuery.[set|get]TokenId()` with no replacement +- `TokenNftInfoQuery.[set|get]Start()` with no replacement +- `TokenNftInfoQuery.[set|get]End()` with no replacement +- `TokenMintTransaction.[add|set]Metadata()` support for string metadata ## v2.0.29 ### Added - * Support for `CustomRoyaltyFees` - * Updated `Status` with new response codes - * Implemented `Client.[set|get]NetworkName()` +- Support for `CustomRoyaltyFees` +- Updated `Status` with new response codes +- Implemented `Client.[set|get]NetworkName()` ## v2.0.28 ### Added - * `Client.pingAll()` - pings all network nodes - * `Client.[set|get]NodeWaitTime()` - minimum delay for nodes that are nto responding - * `Client.[set|get]MaxAttempts()` - max number of attempts for each request - * `Client.[set|get]MaxNodesPerTransaction()` - number of node account IDs to use per request - * `CustomFixedFee.[set|get]HbarAmount()` - helper method to set both `denominatingTokenId` and `amount` when fee is an `Hbar` amount - * `CustomFixedFee.setDenominatingTokenToSameToken()` - helper method to set `denominatingTokenId` to `0.0.0` which is not obvious +- `Client.pingAll()` - pings all network nodes +- `Client.[set|get]NodeWaitTime()` - minimum delay for nodes that are nto responding +- `Client.[set|get]MaxAttempts()` - max number of attempts for each request +- `Client.[set|get]MaxNodesPerTransaction()` - number of node account IDs to use per request +- `CustomFixedFee.[set|get]HbarAmount()` - helper method to set both `denominatingTokenId` and `amount` when fee is an `Hbar` amount +- `CustomFixedFee.setDenominatingTokenToSameToken()` - helper method to set `denominatingTokenId` to `0.0.0` which is not obvious ### Changed - * `Client.ping()` will no longer throw an error +- `Client.ping()` will no longer throw an error ### Deprecated - * `*[Transaction|Query].[set|get]MaxRetries()` - Use `*[Transaction|Query].[set|get]MaxAttempts()` instead +- `*[Transaction|Query].[set|get]MaxRetries()` - Use `*[Transaction|Query].[set|get]MaxAttempts()` instead ### Fixed - * `PrivateKey.signTransaction()` and `PublicKey.verifyTransaction()` should correctly freeze an unfrozen transaction +- `PrivateKey.signTransaction()` and `PublicKey.verifyTransaction()` should correctly freeze an unfrozen transaction ## v2.0.27 ### Added - * Updated `Status` with new response codes - * Support for `Hbar.[from|to]String()` to be reversible - * `Client.setAutoValidateChecksums()` set whether checksums on ids will be automatically validated upon attempting to execute a transaction or query. Disabled by default. Check status with `Client.isAutoValidateChecksumsEnabled()` - * `*Id.toString()` no longer stringifies with checksums. Use `*Id.getChecksum()` to get the checksum that was parsed, or use `*Id.toStringWithChecksum(client)` to stringify with the correct checksum for that ID on the client's network. - * `*Id.validateChecksum()` to validate a checksum. Throws new `BadEntityIdException` +- Updated `Status` with new response codes +- Support for `Hbar.[from|to]String()` to be reversible +- `Client.setAutoValidateChecksums()` set whether checksums on ids will be automatically validated upon attempting to execute a transaction or query. Disabled by default. Check status with `Client.isAutoValidateChecksumsEnabled()` +- `*Id.toString()` no longer stringifies with checksums. Use `*Id.getChecksum()` to get the checksum that was parsed, or use `*Id.toStringWithChecksum(client)` to stringify with the correct checksum for that ID on the client's network. +- `*Id.validateChecksum()` to validate a checksum. Throws new `BadEntityIdException` ### Fixed - * Free queries should not longer attempt to sign payment transactions - * All enitty IDs within response should no longer contain a checskum. - Use `*Id.toStringWithChecksum(Client)` to stringify with a checksum - * `ReceiptStatusError` should contain a properly filled out `TransactionReceipt` +- Free queries should not longer attempt to sign payment transactions +- All enitty IDs within response should no longer contain a checskum. + Use `*Id.toStringWithChecksum(Client)` to stringify with a checksum +- `ReceiptStatusError` should contain a properly filled out `TransactionReceipt` ### Deprecated - * `*Id.validate()` use `*Id.validateChecksum()` instead +- `*Id.validate()` use `*Id.validateChecksum()` instead ## v2.0.26 ### Changed - * Updated `Status` and `FeeDataType` with new codes +- Updated `Status` and `FeeDataType` with new codes ## v2.0.25 ### Added - * `TokenCreateTransaction.[get|set]FeeScheduleKey()` - * Support for parsing file 0.0.111 using `FeeSchedules` +- `TokenCreateTransaction.[get|set]FeeScheduleKey()` +- Support for parsing file 0.0.111 using `FeeSchedules` ### Fixed - * `TokenMintTransaction.[to|from]Bytes()` incorrectly parsing the transaction body +- `TokenMintTransaction.[to|from]Bytes()` incorrectly parsing the transaction body ### Removed - * `TokenCreateTransaction.addCustomFee()` - use `TokenCreateTransaction.setCustomFees()` instead +- `TokenCreateTransaction.addCustomFee()` - use `TokenCreateTransaction.setCustomFees()` instead ## v2.0.25-beta.1 ### Added - * Support for NFTS - * Creating NFT tokens - * Minting NFTs - * Burning NFTs - * Transfering NFTs - * Wiping NFTs - * Query NFT information - * Support for Custom Fees on tokens: - * Setting custom fees on a token - * Updating custom fees on an existing token +- Support for NFTS + - Creating NFT tokens + - Minting NFTs + - Burning NFTs + - Transfering NFTs + - Wiping NFTs + - Query NFT information +- Support for Custom Fees on tokens: + - Setting custom fees on a token + - Updating custom fees on an existing token ### Fixed - * Loading keystore should no longer error when `CipherAlgorithm` doesn't match case - * `PrivateKey.legacyDerive()` should now be consistent with the v1.4.6 JS SDK +- Loading keystore should no longer error when `CipherAlgorithm` doesn't match case +- `PrivateKey.legacyDerive()` should now be consistent with the v1.4.6 JS SDK ## v2.0.24 ### Added - * `Hbar.fromTinybar()` supports `BigNumber` - * `Hbar.toString()` supports `HbarUnit` - * Implemented to and from bytes for `TopicInfo` and `TokenInfo` - * Support for `sign-on-demand` - * This is disabled by default to you'll need to enable it using `Client.setSignOnDemand(true)` - * If `sign-on-demand` is enabled you'll need to use `async` versions of these methods: - * `*Transaction.toBytes()` -> `*Transaction.toBytesAsync()` - * `*Transaction.getSignatures()` -> `*Transaction.getSignaturesAsync()` - * `*Transaction.getTransactionHash()` -> `*Transaction.getTransactionHashAsync()` +- `Hbar.fromTinybar()` supports `BigNumber` +- `Hbar.toString()` supports `HbarUnit` +- Implemented to and from bytes for `TopicInfo` and `TokenInfo` +- Support for `sign-on-demand` + - This is disabled by default to you'll need to enable it using `Client.setSignOnDemand(true)` + - If `sign-on-demand` is enabled you'll need to use `async` versions of these methods: + - `*Transaction.toBytes()` -> `*Transaction.toBytesAsync()` + - `*Transaction.getSignatures()` -> `*Transaction.getSignaturesAsync()` + - `*Transaction.getTransactionHash()` -> `*Transaction.getTransactionHashAsync()` ### Changes - * All requests now retry on gRPC status `INTERNAL` if error returned contains `RST_STREAM` +- All requests now retry on gRPC status `INTERNAL` if error returned contains `RST_STREAM` ## v2.0.23 ### Added - * Added support for TLS on mirror node connections - * Implemented `*Id.clone()` (this is used internally to fix some issues that only surface in React Native) - * Implement `Timestamp.plusNanos()` - * Added support for entity ID checksums. The network will be extracted from the checksum of the - entity ID and validated on each request to make sure a request is not happening on one network - while an entity ID references another network. Entity IDs with a network will print with a checksum - while entity IDs without a checksum will not print the checksum part. +- Added support for TLS on mirror node connections +- Implemented `*Id.clone()` (this is used internally to fix some issues that only surface in React Native) +- Implement `Timestamp.plusNanos()` +- Added support for entity ID checksums. The network will be extracted from the checksum of the + entity ID and validated on each request to make sure a request is not happening on one network + while an entity ID references another network. Entity IDs with a network will print with a checksum + while entity IDs without a checksum will not print the checksum part. ### Fixed - * `TopicMessageQuery.startTime` not updating start time by one nanosecond causing a message to appear twice - if the connection reset - * `TopicMessageQuery` should log retries - * `TransactionReceipt` error handling; this should now throw an error contain the receipt +- `TopicMessageQuery.startTime` not updating start time by one nanosecond causing a message to appear twice + if the connection reset +- `TopicMessageQuery` should log retries +- `TransactionReceipt` error handling; this should now throw an error contain the receipt ## v2.0.22 ### Fixed - * `TopicMessageQuery.maxBackoff` was not being used at all - * `TopicMessageQuery.limit` was being incorrectly update with full `TopicMessages` rather than per chunk - * `TopicMessageQuery.startTime` was not being updated each time a message was received - * `TopicMessageQuery.completionHandler` was be called at incorrect times +- `TopicMessageQuery.maxBackoff` was not being used at all +- `TopicMessageQuery.limit` was being incorrectly update with full `TopicMessages` rather than per chunk +- `TopicMessageQuery.startTime` was not being updated each time a message was received +- `TopicMessageQuery.completionHandler` was be called at incorrect times ## v2.0.21 ### Added - * Exposed `AccountBalance.tokenDecimals` - * Support for `string` parameters in `Hbar.fromTinybars()` - * `Hbar.toBigNumber()` which is a simple wrapper around `Hbar.to(HbarUnit.Hbar)` - * `AccountBalance.toJSON()` - * Support for `maxBackoff`, `maxAttempts`, `retryHandler`, and `completionHandler` in `TopicMessageQuery` - * Default logging behavior to `TopicMessageQuery` if an error handler or completion handler was not set +- Exposed `AccountBalance.tokenDecimals` +- Support for `string` parameters in `Hbar.fromTinybars()` +- `Hbar.toBigNumber()` which is a simple wrapper around `Hbar.to(HbarUnit.Hbar)` +- `AccountBalance.toJSON()` +- Support for `maxBackoff`, `maxAttempts`, `retryHandler`, and `completionHandler` in `TopicMessageQuery` +- Default logging behavior to `TopicMessageQuery` if an error handler or completion handler was not set ### Fixed - * `TopicMessageQuery` retry handling; this should retry on more gRPC errors - * `TopicMessageQuery` max retry timeout; before this would could wait up to 4m with no feedback - * Missing `@readonly` tag on `TokenInfo.tokenMemo` - * `Keystore` failing to recognize keystores generated by v1 SDKs - * Errors caused by the use `?.` and `??` within a node 12 context - * `TopicMessageQuery` +- `TopicMessageQuery` retry handling; this should retry on more gRPC errors +- `TopicMessageQuery` max retry timeout; before this would could wait up to 4m with no feedback +- Missing `@readonly` tag on `TokenInfo.tokenMemo` +- `Keystore` failing to recognize keystores generated by v1 SDKs +- Errors caused by the use `?.` and `??` within a node 12 context +- `TopicMessageQuery` ## v2.0.20 ### Added - * `PrivateKey.legacyDerive()` - Derive private key using legacy derivations - * `Hbar.fromTinybars()` supports `string` parameter - * `Hbar.toBigNumber()` aliases `Hbar.to(HbarUnit.Hbar)` - * `AccountBalance.tokenDecimals` - Represents the decimals on a token - * `AccountBalance.toString()` should print a `JSON.stringified()` output - * `AccountBalance.toJSON()` +- `PrivateKey.legacyDerive()` - Derive private key using legacy derivations +- `Hbar.fromTinybars()` supports `string` parameter +- `Hbar.toBigNumber()` aliases `Hbar.to(HbarUnit.Hbar)` +- `AccountBalance.tokenDecimals` - Represents the decimals on a token +- `AccountBalance.toString()` should print a `JSON.stringified()` output +- `AccountBalance.toJSON()` ### Changed - * `Mnemonic.toLegacyPrivateKey()` no longer automaticaly derives `PrivateKey`, instead produces root `PrivateKey` - Use `PrivateKey.legacyDerive()` to derive the proper `PrivateKey` manually - * Removed the use of `@hashgraph/protobufjs` in favor of `protobufjs` - The reason `@hashgraph/protobufjs` even exists is because `protobufjs` contains `eval` - which fails CSP in browser. However, while running integration tests through `vite` and - `mocha` it seems the `eval` was never hit. - * Moved from `yarn` to `pnpm` because of performance issues with `yarn` +- `Mnemonic.toLegacyPrivateKey()` no longer automaticaly derives `PrivateKey`, instead produces root `PrivateKey` + Use `PrivateKey.legacyDerive()` to derive the proper `PrivateKey` manually +- Removed the use of `@hashgraph/protobufjs` in favor of `protobufjs` + The reason `@hashgraph/protobufjs` even exists is because `protobufjs` contains `eval` + which fails CSP in browser. However, while running integration tests through `vite` and + `mocha` it seems the `eval` was never hit. +- Moved from `yarn` to `pnpm` because of performance issues with `yarn` ## v2.0.19 ### Added - * Scheduled transaction support: `ScheduleCreateTransaction`, `ScheduleDeleteTransaction`, and `ScheduleSignTransaction` - * React Native support - * Support for raw `proto.Transaction` bytes in `Transaction.fromBytes()` - * This means v1 SDK's `Transaction.toBytes()` will now be supported in v2 `Transaction.fromBytes()` - However, `Transaction.toBytes()` and `Transaction.getTransactionHas()` in v2 will produce different - results in the v1 SDK's. +- Scheduled transaction support: `ScheduleCreateTransaction`, `ScheduleDeleteTransaction`, and `ScheduleSignTransaction` +- React Native support +- Support for raw `proto.Transaction` bytes in `Transaction.fromBytes()` + - This means v1 SDK's `Transaction.toBytes()` will now be supported in v2 `Transaction.fromBytes()` + However, `Transaction.toBytes()` and `Transaction.getTransactionHas()` in v2 will produce different + results in the v1 SDK's. ### Fixed - * addSignature() Behavior Differs Between Implementations [NCC-E001154-005] - * Decreased `CHUNK_SIZE` 4096->1024 and increased default max chunks 10->20 - * Export `StatusError`, `PrecheckStatusError`, `ReceiptStatusError`, and `BadKeyError` - * `KeyList.toString()` - * `AccountBalance.toString()` +- addSignature() Behavior Differs Between Implementations [NCC-E001154-005] +- Decreased `CHUNK_SIZE` 4096->1024 and increased default max chunks 10->20 +- Export `StatusError`, `PrecheckStatusError`, `ReceiptStatusError`, and `BadKeyError` +- `KeyList.toString()` +- `AccountBalance.toString()` ### Deprecated - * `new TransactionId(AccountId, Instant)` - Use `TransactionId.withValidStart()` instead. +- `new TransactionId(AccountId, Instant)` - Use `TransactionId.withValidStart()` instead. ## v2.0.18 - Deprecated @@ -1126,15 +1154,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - * addSignature() Behavior Differs Between Implementations [NCC-E001154-005] - * Decreased `CHUNK_SIZE` 4096->1024 and increased default max chunks 10->20 - * Renamed `ScheduleInfo.getTransaction()` -> `ScheduleInfo.getScheduledTransaction()` +- addSignature() Behavior Differs Between Implementations [NCC-E001154-005] +- Decreased `CHUNK_SIZE` 4096->1024 and increased default max chunks 10->20 +- Renamed `ScheduleInfo.getTransaction()` -> `ScheduleInfo.getScheduledTransaction()` ## v2.0.17-beta.6 ### Added - * React Native support +- React Native support ## v2.0.17-beta.5 - Deprecated @@ -1142,87 +1170,90 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - * Scheduled transactions should use new HAPI protobufs - * Removed `nonce` from `TransactionId` - * `schedule-multi-sig-transaction` example to use new scheduled transaction API +- Scheduled transactions should use new HAPI protobufs +- Removed `nonce` from `TransactionId` +- `schedule-multi-sig-transaction` example to use new scheduled transaction API ### Removed - * `ScheduleCreateTransaction.addScheduledSignature()` - * `ScheduleCreateTransaction.scheduledSignatures()` - * `ScheduleSignTransaction.addScheduledSignature()` - * `ScheduleSignTransaction.scheduledSignatures()` + +- `ScheduleCreateTransaction.addScheduledSignature()` +- `ScheduleCreateTransaction.scheduledSignatures()` +- `ScheduleSignTransaction.addScheduledSignature()` +- `ScheduleSignTransaction.scheduledSignatures()` ## v2.0.17-beta.3 ### Added - * Support for raw `proto.Transaction` bytes in `Transaction.fromBytes()` - * This means v1 SDK's `Transaction.toBytes()` will now be supported in v2 `Transaction.fromBytes()` - However, `Transaction.toBytes()` and `Transaction.getTransactionHas()` in v2 will produce different - results in the v1 SDK's. - * Export `StatusError`, `PrecheckStatusError`, `ReceiptStatusError`, and `BadKeyError` +- Support for raw `proto.Transaction` bytes in `Transaction.fromBytes()` + - This means v1 SDK's `Transaction.toBytes()` will now be supported in v2 `Transaction.fromBytes()` + However, `Transaction.toBytes()` and `Transaction.getTransactionHas()` in v2 will produce different + results in the v1 SDK's. +- Export `StatusError`, `PrecheckStatusError`, `ReceiptStatusError`, and `BadKeyError` ### Fixed - * A few examples that did not work with `CONFIG_FILE` environment variable +- A few examples that did not work with `CONFIG_FILE` environment variable ## v2.0.17-beta.2 ### Added - * Support for setting signatures on the underlying scheduled transaction - * `TransactionReceipt.scheduledTransactionId` - * `ScheduleInfo.scheduledTransactionId` - * `TransactionRecord.scheduleRef` - * Support for scheduled and nonce in `TransactionId` - * `TransactionId.withNonce()` - Supports creating transaction ID with random bytes. - * `TransactionId.[set|get]Scheduled()` - Supports scheduled transaction IDs. - * `memo` fields for both create and update transactions and info queries - * `Account[Create|Update]Transaction.[set|get]AccountMemo()` - * `File[Create|Update]Transaction.[set|get]AccountMemo()` - * `Token[Create|Update]Transaction.[set|get]AccountMemo()` - * `AccountInfoQuery.accountMemo` - * `FileInfoQuery.fileMemo` - * `TokenInfoQuery.tokenMemo` +- Support for setting signatures on the underlying scheduled transaction +- `TransactionReceipt.scheduledTransactionId` +- `ScheduleInfo.scheduledTransactionId` +- `TransactionRecord.scheduleRef` +- Support for scheduled and nonce in `TransactionId` + - `TransactionId.withNonce()` - Supports creating transaction ID with random bytes. + - `TransactionId.[set|get]Scheduled()` - Supports scheduled transaction IDs. +- `memo` fields for both create and update transactions and info queries + - `Account[Create|Update]Transaction.[set|get]AccountMemo()` + - `File[Create|Update]Transaction.[set|get]AccountMemo()` + - `Token[Create|Update]Transaction.[set|get]AccountMemo()` + - `AccountInfoQuery.accountMemo` + - `FileInfoQuery.fileMemo` + - `TokenInfoQuery.tokenMemo` ### Fixed - * `ScheduleInfo.*ID` field names should use `Id` - Ex. `ScheduleInfo.creatorAccountID` -> `ScheduleInfo.creatorAccountId` - * Renamed `ScheduleInfo.memo` -> `ScheduleInfo.scheduleMemo` - * Chunked transactions should not support scheduling if the data provided is too large - * `TopicMessageSubmitTransaction` - * `FileAppendTransaction` +- `ScheduleInfo.*ID` field names should use `Id` + Ex. `ScheduleInfo.creatorAccountID` -> `ScheduleInfo.creatorAccountId` +- Renamed `ScheduleInfo.memo` -> `ScheduleInfo.scheduleMemo` +- Chunked transactions should not support scheduling if the data provided is too large + - `TopicMessageSubmitTransaction` + - `FileAppendTransaction` ## v2.0.17-beta.1 ### Added - * Support for scheduled transactions. - * `ScheduleCreateTransaction` - Create a new scheduled transaction - * `ScheduleSignTransaction` - Sign an existing scheduled transaction on the network - * `ScheduleDeleteTransaction` - Delete a scheduled transaction - * `ScheduleInfoQuery` - Query the info including `bodyBytes` of a scheduled transaction - * `ScheduleId` +- Support for scheduled transactions. + - `ScheduleCreateTransaction` - Create a new scheduled transaction + - `ScheduleSignTransaction` - Sign an existing scheduled transaction on the network + - `ScheduleDeleteTransaction` - Delete a scheduled transaction + - `ScheduleInfoQuery` - Query the info including `bodyBytes` of a scheduled transaction + - `ScheduleId` ### Fixed - * `KeyList.toString()` - * `AccountBalance.toString()` +- `KeyList.toString()` +- `AccountBalance.toString()` ### Deprecated - * `new TransactionId(AccountId, Instant)` - Use `TransactionId.withValidStart()` instead. +- `new TransactionId(AccountId, Instant)` - Use `TransactionId.withValidStart()` instead. ## v2.0.15 ### Added - * Implement `Client.forName()` to support construction of client from network name. - * Implement `PrivateKey.verifyTransaction()` to allow a user to verify a transaction was signed with a partiular key. + +- Implement `Client.forName()` to support construction of client from network name. +- Implement `PrivateKey.verifyTransaction()` to allow a user to verify a transaction was signed with a partiular key. ## v2.0.14 ### General Changes + * All queries and transactions support setting fields in the constructor using an object, e.g. `new AccountBalanceQuery({ accountId: "0.0.3" })`, or `new AccountCreateTransaction({ key: client.operatorPublicKey, initialBalance: 10 })`. @@ -1232,146 +1263,147 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - * `Ed25519PrivateKey.fromMnemonic` regressed in v1.1.8 and was not working in the browser. +- `Ed25519PrivateKey.fromMnemonic` regressed in v1.1.8 and was not working in the browser. - * Use detached signatures when signing the transaction. This should allow for much larger transactions to be submitted. +- Use detached signatures when signing the transaction. This should allow for much larger transactions to be submitted. ## v1.1.11 ### Fixed - * `Ed25519PrivateKey.fromKeystore` regressed in v1.1.9 and was not working in the browser +- `Ed25519PrivateKey.fromKeystore` regressed in v1.1.9 and was not working in the browser ## v1.1.10 ### Added - * `Client.ping(id: AccountIdLike)` Pings a node by account ID. +- `Client.ping(id: AccountIdLike)` Pings a node by account ID. - * `Ed25519PrivateKey.fromMnemonic` works with legacy 22-word phrases. +- `Ed25519PrivateKey.fromMnemonic` works with legacy 22-word phrases. ### Deprecated - * `Client.getAccountBalance()` to match the Java SDK. Use `AccountBalanceQuery` directly instead. +- `Client.getAccountBalance()` to match the Java SDK. Use `AccountBalanceQuery` directly instead. ## v1.1.9 ### Added - * Allow BigNumber or String to be used as Tinybar where Tinybar was accepted +- Allow BigNumber or String to be used as Tinybar where Tinybar was accepted - * Add support for decoding `Ed25519PrivateKey` from a PEM file using `Ed25519PrivateKey.fromPem()` +- Add support for decoding `Ed25519PrivateKey` from a PEM file using `Ed25519PrivateKey.fromPem()` - * Add support for passing no argument to `ContractFunctionResult.get*()` methods. +- Add support for passing no argument to `ContractFunctionResult.get*()` methods. - * Add `MnemonicValidationResult` which is the response type for `Mnemonic.validte()` +- Add `MnemonicValidationResult` which is the response type for `Mnemonic.validte()` - * Add public method `Mnemonic.validate(): MnemonicValidationResult` which validates if the mnemonic - came from the same wordlist, in the right order, and without misspellings. +- Add public method `Mnemonic.validate(): MnemonicValidationResult` which validates if the mnemonic + came from the same wordlist, in the right order, and without misspellings. - * Add `BadPemFileError` which is thrown when decoding a pem file fails. +- Add `BadPemFileError` which is thrown when decoding a pem file fails. ### Fixed - * Fixes `AddBytes32Array` +- Fixes `AddBytes32Array` - * Fixes `Hbar.isNegative()` failing with `undefined`. +- Fixes `Hbar.isNegative()` failing with `undefined`. - * Fixes `CryptoTransferTransaction.addTransfer()` not supporting `BigNumber` or - `number` as arguments. +- Fixes `CryptoTransferTransaction.addTransfer()` not supporting `BigNumber` or + `number` as arguments. - * Fixes `ConsensusTopicInfoQuery.setTopicId()` not supporting `ConsensusTopicIdLike`. +- Fixes `ConsensusTopicInfoQuery.setTopicId()` not supporting `ConsensusTopicIdLike`. ### Deprecated - * Deprecates `Client.maxTransactionFee` and `Client.maxQueryPayment` getters. +- Deprecates `Client.maxTransactionFee` and `Client.maxQueryPayment` getters. - * Deprecates `ConsensusTopicCreateTransaction.setAutoRenewAccount()` was simply - renamed to `ConsensusTopicCreateTransaction.setAutoRenewAccountId()`. +- Deprecates `ConsensusTopicCreateTransaction.setAutoRenewAccount()` was simply + renamed to `ConsensusTopicCreateTransaction.setAutoRenewAccountId()`. - * Deprecates `ConsensusTopicCreateTransaction.setExpirationTime()` with no replacement. +- Deprecates `ConsensusTopicCreateTransaction.setExpirationTime()` with no replacement. - * Deprecates `ConsensusTopicCreateTransaction.setValidStart()` with no replacement. +- Deprecates `ConsensusTopicCreateTransaction.setValidStart()` with no replacement. - * Deprecates `ConsensusTopicUpdateTransaction.setAutoRenewAccount()` with no replacement. +- Deprecates `ConsensusTopicUpdateTransaction.setAutoRenewAccount()` with no replacement. ## v1.1.8 ### Fixed - * `TransactionRecord.getContractCallResult` and `TransactionRecord.getContractExecuteResult` were swapped +- `TransactionRecord.getContractCallResult` and `TransactionRecord.getContractExecuteResult` were swapped internally and neither worked before. - * Export `ConsensusMessageSubmitTransaction`. +- Export `ConsensusMessageSubmitTransaction`. ## v1.1.7 ### Fixed - * Do not provide (and sign) a payment transaction for `AccountBalanceQuery`. It is not required. +- Do not provide (and sign) a payment transaction for `AccountBalanceQuery`. It is not required. ## v1.1.6 ### Added - * Add `TransactionBuilder.getCost()` to return a very close estimate of the transaction fee (within 1%). +- Add `TransactionBuilder.getCost()` to return a very close estimate of the transaction fee (within 1%). + +- Add additional error classes to allow more introspection on errors: - * Add additional error classes to allow more introspection on errors: - * `HederaPrecheckStatusError` - Thrown when the transaction fails at the node (the precheck) - * `HederaReceiptStatusError` - Thrown when the receipt is checked and has a failing status. The error object contains the full receipt. - * `HederaRecordStatusError` - Thrown when the record is checked and it has a failing status. The error object contains the full record. + - `HederaPrecheckStatusError` - Thrown when the transaction fails at the node (the precheck) + - `HederaReceiptStatusError` - Thrown when the receipt is checked and has a failing status. The error object contains the full receipt. + - `HederaRecordStatusError` - Thrown when the record is checked and it has a failing status. The error object contains the full record. - * `console.log(obj)` now prints out nice debug information for several types in the SDK including receipts +- `console.log(obj)` now prints out nice debug information for several types in the SDK including receipts ## v1.1.5 ### Added - * Add `TransactionReceipt.getConsensusTopicId()`. +- Add `TransactionReceipt.getConsensusTopicId()`. - * Add `TransactionReceipt.getConsensusTopicRunningHash()`. +- Add `TransactionReceipt.getConsensusTopicRunningHash()`. - * Add `TransactionReceipt.getConsensusTopicSequenceNumber()`. +- Add `TransactionReceipt.getConsensusTopicSequenceNumber()`. - * Adds support for addresses with a leading `0x` prefix with `ContractFunctionParams.addAddress()`. +- Adds support for addresses with a leading `0x` prefix with `ContractFunctionParams.addAddress()`. ### Deprecated - * Deprecates `Client.putNode()`. Use `Client.replaceNodes()` instead. +- Deprecates `Client.putNode()`. Use `Client.replaceNodes()` instead. - * Depreactes `Transaction.getReceipt()` and `Transaction.getRecord()`. Use `TransactionId.getReceipt()` or - `TransactionId.getRecord()` instead. The `execute` method on `Transaction` returns a `TransactionId`. +- Depreactes `Transaction.getReceipt()` and `Transaction.getRecord()`. Use `TransactionId.getReceipt()` or + `TransactionId.getRecord()` instead. The `execute` method on `Transaction` returns a `TransactionId`. - * Deprecates `ConsensusSubmitMessageTransaction`. This was renamed to `ConsensusMessageSubmitTransaction` to - match the Java SDK. +- Deprecates `ConsensusSubmitMessageTransaction`. This was renamed to `ConsensusMessageSubmitTransaction` to + match the Java SDK. ## v1.1.2 ### Fixed - * https://github.com/hashgraph/hedera-sdk-js/issues/175 +- https://github.com/hashgraph/hedera-sdk-js/issues/175 ## v1.1.1 ### Fixed - * `RECEIPT_NOT_FOUND` is properly considered and internally retried within `TransactionReceiptQuery` +- `RECEIPT_NOT_FOUND` is properly considered and internally retried within `TransactionReceiptQuery` ## v1.1.0 ### Fixed - * Contract parameter encoding with BigNumbers +- Contract parameter encoding with BigNumbers ### Added Add support for Hedera Consensus Service (HCS). - * Add `ConsensusTopicCreateTransaction`, `ConsensusTopicUpdateTransaction`, `ConsensusTopicDeleteTransaction`, and `ConsensusMessageSubmitTransaction` transactions +- Add `ConsensusTopicCreateTransaction`, `ConsensusTopicUpdateTransaction`, `ConsensusTopicDeleteTransaction`, and `ConsensusMessageSubmitTransaction` transactions - * Add `ConsensusTopicInfoQuery` query (returns `ConsensusTopicInfo`) +- Add `ConsensusTopicInfoQuery` query (returns `ConsensusTopicInfo`) - * Add `MirrorClient` and `MirrorConsensusTopicQuery` which can be used to listen for HCS messages from a mirror node. +- Add `MirrorClient` and `MirrorConsensusTopicQuery` which can be used to listen for HCS messages from a mirror node. ### Changed @@ -1379,33 +1411,33 @@ Minor version bumps may add deprecations as we improve parity between SDKs or fix reported issues. Do not worry about upgrading in a timely manner. All v1+ APIs will be continuously supported. - * Deprecated `SystemDelete#setId`; replaced with `SystemDelete#setFileId` or `SystemDelete#setContractId` +- Deprecated `SystemDelete#setId`; replaced with `SystemDelete#setFileId` or `SystemDelete#setContractId` - * Deprecated `SystemUndelete#setId`; replaced with `SystemUndelete#setFileId` or `SystemUndelete#setContractId` +- Deprecated `SystemUndelete#setId`; replaced with `SystemUndelete#setFileId` or `SystemUndelete#setContractId` - * Deprecated `Hbar.of(val)`; replaced with `new Hbar(val)` +- Deprecated `Hbar.of(val)`; replaced with `new Hbar(val)` - * Deprecated `FreezeTransaction#setStartTime(Date)`; replaced with `FreezeTransaction#setStartTime(hour: number, minute: number)` +- Deprecated `FreezeTransaction#setStartTime(Date)`; replaced with `FreezeTransaction#setStartTime(hour: number, minute: number)` - * Deprecated `FreezeTransaction#setEndTime(Date)`; replaced with `FreezeTransaction#setEndTime(hour: number, minute: number)` +- Deprecated `FreezeTransaction#setEndTime(Date)`; replaced with `FreezeTransaction#setEndTime(hour: number, minute: number)` - * All previous exception types are no longer thrown. Instead there are a set of new exception types to match the Java SDK. +- All previous exception types are no longer thrown. Instead there are a set of new exception types to match the Java SDK. - * `HederaError` becomes `HederaStatusError` - * `ValidationError` becomes `LocalValidationError` - * `TinybarValueError` becomes `HbarRangeError` - * `MaxPaymentExceededError` becomes `MaxQueryPaymentExceededError` - * `BadKeyError` is a new exception type when attempting to parse or otherwise use a key that doesn't look like a key + - `HederaError` becomes `HederaStatusError` + - `ValidationError` becomes `LocalValidationError` + - `TinybarValueError` becomes `HbarRangeError` + - `MaxPaymentExceededError` becomes `MaxQueryPaymentExceededError` + - `BadKeyError` is a new exception type when attempting to parse or otherwise use a key that doesn't look like a key ## v1.0.1 ### Added - * Allow passing a string for a private key in `Client.setOperator` +- Allow passing a string for a private key in `Client.setOperator` ### Fixed - * Correct list of testnet node addresses +- Correct list of testnet node addresses ## v1.0.0 @@ -1415,100 +1447,102 @@ No significant changes since v1.0.0-beta.5 ### Fixed - * Fix `getCost` for entity Info queries where the entity was deleted +- Fix `getCost` for entity Info queries where the entity was deleted ### Added - * Add support for unsigned integers (incl. Arrays) for contract encoding and decoding +- Add support for unsigned integers (incl. Arrays) for contract encoding and decoding - * Add `AccountUpdateTransaction.setReceiverSignatureRequired` +- Add `AccountUpdateTransaction.setReceiverSignatureRequired` - * Add `AccountUpdateTransaction.setProxyAccountId` +- Add `AccountUpdateTransaction.setProxyAccountId` ### Changed - * Rename `ContractExecuteTransaction.setAmount()` to `ContractExecuteTransaction.setPayableAmount()` +- Rename `ContractExecuteTransaction.setAmount()` to `ContractExecuteTransaction.setPayableAmount()` ## v1.0.0-beta.4 ### Added - * `Client.forTestnet` makes a new client configured to talk to TestNet (use `.setOperator` to set an operater) +- `Client.forTestnet` makes a new client configured to talk to TestNet (use `.setOperator` to set an operater) - * `Client.forMainnet` makes a new client configured to talk to Mainnet (use `.setOperator` to set an operater) +- `Client.forMainnet` makes a new client configured to talk to Mainnet (use `.setOperator` to set an operater) ### Changed - * Renamed `TransactionReceipt.accountId`, `TransactionReceipt.contractId`, `TransactionReceipt.fileId`, and - `TransactionReceipt.contractId` to `TransactionReceipt.getAccountId()`, etc. to add an explicit illegal - state check as these fields are mutually exclusive +- Renamed `TransactionReceipt.accountId`, `TransactionReceipt.contractId`, `TransactionReceipt.fileId`, and + `TransactionReceipt.contractId` to `TransactionReceipt.getAccountId()`, etc. to add an explicit illegal + state check as these fields are mutually exclusive - * Renamed `TransactionRecord.contractCallResult` to `TransactionRecord.getContractExecuteResult()` +- Renamed `TransactionRecord.contractCallResult` to `TransactionRecord.getContractExecuteResult()` - * Renamed `TransactionRecord.contractCreateResult` to `TransactionRecord.getContractCreateResult()` +- Renamed `TransactionRecord.contractCreateResult` to `TransactionRecord.getContractCreateResult()` ## v1.0.0-beta.3 ### Changed - * `TransactionBuilder.setMemo` is renamed to `TransactionBuilder.setTransactionMemo` to avoid confusion - as there are 2 other kinds of memos on transactions +- `TransactionBuilder.setMemo` is renamed to `TransactionBuilder.setTransactionMemo` to avoid confusion + as there are 2 other kinds of memos on transactions ### Fixed - * Fix usage on Node versions less than 12.x +- Fix usage on Node versions less than 12.x ## v1.0.0-beta.2 ### Changed - * `CallParams` is removed in favor of `ContractFunctionParams` and closely mirrors type names from solidity - * `addInt32` - * `addInt256Array` - * `addString` - * etc. +- `CallParams` is removed in favor of `ContractFunctionParams` and closely mirrors type names from solidity + + - `addInt32` + - `addInt256Array` + - `addString` + - etc. + +- `ContractFunctionResult` now closely mirrors the solidity type names - * `ContractFunctionResult` now closely mirrors the solidity type names - * `getInt32` - * etc. + - `getInt32` + - etc. - * `setFunctionParams(params)` on `ContractCallQuery` and `ContractExecuteTransaction` is now - `setFunction(name, params)` +- `setFunctionParams(params)` on `ContractCallQuery` and `ContractExecuteTransaction` is now + `setFunction(name, params)` - * `ContractLogInfo.topicList` -> `ContractLogInfo.topics` +- `ContractLogInfo.topicList` -> `ContractLogInfo.topics` - * `FileInfo.deleted` -> `FileInfo.isDeleted` +- `FileInfo.deleted` -> `FileInfo.isDeleted` - * `FileContentsQuery.execute` now directly returns `Uint8Array` +- `FileContentsQuery.execute` now directly returns `Uint8Array` - * `ContractRecordsQuery.execute` now directly returns `TransactionRecord[]` +- `ContractRecordsQuery.execute` now directly returns `TransactionRecord[]` - * `AccountAmount.amount` (`String`) -> `AccountAmount.amount` (`Hbar`) +- `AccountAmount.amount` (`String`) -> `AccountAmount.amount` (`Hbar`) - * TransactionReceipt - * `receiverSigRequired` -> `isReceiverSignatureRequired` - * `autoRenewPeriodSeconds` -> `autoRenewPeriod` +- TransactionReceipt + - `receiverSigRequired` -> `isReceiverSignatureRequired` + - `autoRenewPeriodSeconds` -> `autoRenewPeriod` ### Fixed - * Remove incorrect local validation for FileCreateTransaction and FileUpdateTransaction +- Remove incorrect local validation for FileCreateTransaction and FileUpdateTransaction - * Any `key` fields on response types (e.g., `AccountInfo`) are - now `PublicKey` and can be any of the applicable key types +- Any `key` fields on response types (e.g., `AccountInfo`) are + now `PublicKey` and can be any of the applicable key types - * Fix transaction back-off when BUSY is returned +- Fix transaction back-off when BUSY is returned - * Default autoRenewPeriod on ContractCreate appropriately +- Default autoRenewPeriod on ContractCreate appropriately ## v0.8.0-beta.3 ### Changed - * Client constructor takes the network as `{ network: ... }` instead of `{ nodes: ... }` +- Client constructor takes the network as `{ network: ... }` instead of `{ nodes: ... }` - * Transactions and queries do not take `Client` in the constructor; instead, `Client` is passed to `execute`. +- Transactions and queries do not take `Client` in the constructor; instead, `Client` is passed to `execute`. - * Removed `Transaction.executeForReceipt` and `Transaction.executeForRecord` +- Removed `Transaction.executeForReceipt` and `Transaction.executeForRecord` These methods have been identified as harmful as they hide too much. If one fails, you do not know if the transaction failed to execute; or, the receipt/record could not be retrieved. In a mission-critical application, that is, of course, an important distinction. @@ -1520,8 +1554,7 @@ No significant changes since v1.0.0-beta.5 let newAccountId = new AccountCreateTransaction(hederaClient) .setKey(newKey.publicKey) .setInitialBalance(1000) - .executeForReceipt() // TransactionReceipt - .accountId; + .executeForReceipt().accountId; // TransactionReceipt ``` v0.8.x and above @@ -1531,30 +1564,29 @@ No significant changes since v1.0.0-beta.5 .setKey(newKey.publicKey) .setInitialBalance(1000) .execute(hederaClient) // TranactionId - .getReceipt(hederaClient) // TransactionReceipt - .accountId; + .getReceipt(hederaClient).accountId; // TransactionReceipt ``` - * Rename `setPaymentDefault` to `setPaymentAmount` +- Rename `setPaymentDefault` to `setPaymentAmount` ### Added - * All transaction and query types that were in the Java SDK but not yet in the JS SDK (GetBySolidityIdQuery, AccountStakersQuery, etc.) +- All transaction and query types that were in the Java SDK but not yet in the JS SDK (GetBySolidityIdQuery, AccountStakersQuery, etc.) - * `TransactionId.getReceipt` +- `TransactionId.getReceipt` - * `TransactionId.getRecord` +- `TransactionId.getRecord` - * `Transaction.toString`. This will dump the transaction (incl. the body) to a stringified JSON object representation of the transaction. Useful for debugging. +- `Transaction.toString`. This will dump the transaction (incl. the body) to a stringified JSON object representation of the transaction. Useful for debugging. - * A default of 1 Hbar is now set for both maximum transaction fees and maximum query payments. +- A default of 1 Hbar is now set for both maximum transaction fees and maximum query payments. - * Smart Contract type encoding and decoding to match Java. +- Smart Contract type encoding and decoding to match Java. - * To/From string methods on AccountId, FileId, etc. +- To/From string methods on AccountId, FileId, etc. - * Internal retry handling for Transactions and Queries (incl. BUSY) +- Internal retry handling for Transactions and Queries (incl. BUSY) ### Removed - * `Transaction` and `Query` types related to claims +- `Transaction` and `Query` types related to claims diff --git a/examples/account-create-evm-address.js b/examples/account-create-evm-address.js deleted file mode 100644 index 68420a07f..000000000 --- a/examples/account-create-evm-address.js +++ /dev/null @@ -1,148 +0,0 @@ -import { - AccountId, - PrivateKey, - Client, - AccountInfoQuery, - AccountCreateTransaction, -} from "@hashgraph/sdk"; -import axios from "axios"; - -import dotenv from "dotenv"; - -dotenv.config(); - -/* -Create an account and set an EVM address using the `AccountCreateTransaction` - -Reference: [HIP-583 Expand alias support in CryptoCreate & CryptoTransfer Transactions](https://hips.hedera.com/hip/hip-583) - -## Example 1 -- Create an ECSDA private key -- Extract the ECDSA public key -- Extract the Ethereum public address -- Add function in the SDK to calculate the Ethereum Address -- Ethereum account address / public-address - This is the rightmost 20 bytes of the 32 byte Keccak-256 hash of the ECDSA public key of the account. This calculation is in the manner described by the Ethereum Yellow Paper. -- Use the `AccountCreateTransaction` and set the EVM address field to the Ethereum public address -- Sign the transaction with the key that us paying for the transaction -- Get the account ID from the receipt -- Get the `AccountInfo` and return the account details -- Verify the evm address provided for the account matches what is in the mirror node -*/ - -async function main() { - if (process.env.OPERATOR_ID == null || process.env.OPERATOR_KEY == null) { - throw new Error( - "Environment variables OPERATOR_ID, and OPERATOR_KEY are required." - ); - } - const operatorId = AccountId.fromString(process.env.OPERATOR_ID); - const operatorKey = PrivateKey.fromString(process.env.OPERATOR_KEY); - - const client = Client.forPreviewnet().setOperator(operatorId, operatorKey); - - /** - * Step 1 - * - * Create an ECSDA private key - */ - const privateKey = PrivateKey.generateECDSA(); - console.log(`Private key: ${privateKey.toStringDer()}`); - - /** - * Step 2 - * - * Extract the ECDSA public key - */ - const publicKey = privateKey.publicKey; - console.log(`Public key: ${publicKey.toStringDer()}`); - /** - * - * Step 3 - * - * Extract the Ethereum public address - */ - const evmAddress = publicKey.toEvmAddress(); - console.log(`Account evm address: ${evmAddress}`); - - /** - * Step 4 - * - * Use the `AccountCreateTransaction` and set the EVM address field to the Ethereum public address - */ - const accountCreateTx = new AccountCreateTransaction() - .setEvmAddress(evmAddress) - .freezeWith(client); - - /** - * Step 5 - * - * Sign the transaction with the key that us paying for the transaction - */ - const accountCreateTxSign = await accountCreateTx.sign(operatorKey); - const accountCreateTxSubmit = await accountCreateTxSign.execute(client); - - /** - * Step 6 - * - * Get the account ID from the receipt - */ - const newAccountId = ( - await accountCreateTxSubmit.getReceipt(client) - ).accountId.toString(); - console.log(`Account ID of the newly created account: ${newAccountId}`); - - /** - * Step 7 - * - * Get the `AccountInfo` and return the account details - */ - const accountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - const accountInfoEvmAddress = accountInfo.contractAccountId; - - /** - * Step 8 - * - * Verify the evm address provided for the account matches what is in the mirror node - */ - const link = `https://${process.env.HEDERA_NETWORK}.mirrornode.hedera.com/api/v1/accounts?account.id=${newAccountId}`; - try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access - let mirrorNodeAccountInfo = (await axios.get(link)).data.accounts[0]; - - // if the request does not succeed, wait for a bit and try again - // the mirror node needs some time to be up to date - while (mirrorNodeAccountInfo == undefined) { - await wait(5000); - mirrorNodeAccountInfo = (await axios.get(link)).data.accounts[0]; // eslint-disable-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access - } - - // here we use .substring(2) because the mirror node returns the evm address with `0x` prefix - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const mirrorNodeEvmAddress = - mirrorNodeAccountInfo.evm_address.substring(2); // eslint-disable-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call - - // check if the generated evm address matches the evm addresses taken from `AccountInfoQuery` and the mirror node - evmAddress === mirrorNodeEvmAddress && - evmAddress === accountInfoEvmAddress - ? console.log( - `The evm address provided for the account matches the one in the mirror node and the one from 'AccountInfoQuery'` - ) - : console.log(`The evm addresses does not match`); - } catch (e) { - console.log(e); - } -} - -/** - * @param {number} timeout - * @returns {Promise} - */ -function wait(timeout) { - return new Promise((resolve) => { - setTimeout(resolve, timeout); - }); -} - -void main(); diff --git a/examples/account-creation-ways.js b/examples/account-creation-ways.js deleted file mode 100644 index 2302fd85e..000000000 --- a/examples/account-creation-ways.js +++ /dev/null @@ -1,58 +0,0 @@ -import { AccountId, PrivateKey } from "@hashgraph/sdk"; - -import dotenv from "dotenv"; - -dotenv.config(); - -function main() { - /* Source and context: https://hips.hedera.com/hip/hip-583 - - In hedera Hedera, we have the concept of 4 different account representations - - An account can have an account ID in shard.realm.accountNumber format (0.0.10) - - An account can have a public key alias in 0.0.CIQNOWUYAGBLCCVX2VF75U6JMQDTUDXBOLZ5VJRDEWXQEGTI64DVCGQ format - - An account can have an AccountId that is represented in 0x000000000000000000000000000000000000000a (for account ID 0.0.10) long zero format - - An account have be represented by an Ethereum public address 0xb794f5ea0ba39494ce839613fffba74279579268 - */ - - /* - Account ID - shard.realm.number format, i.e. `0.0.10` with the corresponding `0x000000000000000000000000000000000000000a` ethereum address - */ - const hederaFormat = AccountId.fromString("0.0.10"); - console.log(`Account ID: ${hederaFormat.toString()}`); - console.log( - `Account 0.0.10 corresponding Long-Zero address: ${hederaFormat.toSolidityAddress()}` - ); - - /* - Hedera Long-Form Account ID - 0.0.aliasPublicKey, i.e. `0.0.CIQNOWUYAGBLCCVX2VF75U6JMQDTUDXBOLZ5VJRDEWXQEGTI64DVCGQ` - */ - const privateKey = PrivateKey.generateECDSA(); - const publicKey = privateKey.publicKey; - - // Assuming that the target shard and realm are known. - // For now they are virtually always 0 and 0. - const aliasAccountId = publicKey.toAccountId(0, 0); - console.log(`Hedera Long-Form Account ID: ${aliasAccountId.toString()}`); - - /* - Hedera Account Long-Zero address - 0x000000000000000000000000000000000000000a (for accountId 0.0.10) - */ - const longZeroAddress = AccountId.fromString( - "0x000000000000000000000000000000000000000a" - ); - console.log( - `Hedera Account Long-Zero address: ${longZeroAddress.toString()}` - ); - - /* - Ethereum Account Address / public-address - 0xb794f5ea0ba39494ce839613fffba74279579268 - */ - const evmAddress = AccountId.fromString( - "0xb794f5ea0ba39494ce839613fffba74279579268" - ); - console.log( - `Ethereum Account Address / public-address: ${evmAddress.toString()}` - ); -} - -void main(); diff --git a/examples/create-account-with-alias.js b/examples/create-account-with-alias.js deleted file mode 100644 index 0bd9590a7..000000000 --- a/examples/create-account-with-alias.js +++ /dev/null @@ -1,263 +0,0 @@ -import { - AccountId, - PrivateKey, - Client, - AccountInfoQuery, - AccountCreateTransaction, -} from "@hashgraph/sdk"; -import axios from "axios"; - -import dotenv from "dotenv"; - -dotenv.config(); - -/* -Create an account and set a public key alias. - -Reference: [HIP-583 Expand alias support in CryptoCreate & CryptoTransfer Transactions](https://hips.hedera.com/hip/hip-583) - -## Example 1: -- Create an ECDSA private key -- Get the ECDSA public key -- Use the `AccountCreateTransaction` and populate the `setAliasKey` field -- Sign the `AccountCreateTransaction` using an existing Hedera account and key to pay for the transaction fee -- Execute the transaction -- Return the Hedera account ID from the receipt of the transaction -- Get the `AccountInfo` using the new account ID -- Get the `AccountInfo` using the account public key in `0.0.aliasPublicKey` format -- Show the public key and the public key alias are the same on the account -- Show this account has a corresponding EVM address in the mirror node - - - -## Example 2: -- Create an ED2519 private key -- Get the ED2519 public key -- Use the `AccountCreateTransaction` and populate the `setAliasKey` field -- Sign the `AccountCreateTransaction` using an existing Hedera account and key to pay for the transaction fee -- Execute the transaction -- Return the Hedera account ID from the receipt of the transaction -- Get the `AccountInfo` using the new account ID -- Get the `AccountInfo` using the account public key in `0.0.aliasPublicKey` format -- Show the public key and the public key alias are the same on the account -*/ - -async function main() { - if (process.env.OPERATOR_ID == null || process.env.OPERATOR_KEY == null) { - throw new Error( - "Environment variables OPERATOR_ID, and OPERATOR_KEY are required." - ); - } - const operatorId = AccountId.fromString(process.env.OPERATOR_ID); - const operatorKey = PrivateKey.fromString(process.env.OPERATOR_KEY); - - const client = Client.forPreviewnet().setOperator(operatorId, operatorKey); - - /** - * Example 1 - * - * Step 1 - * - * Create an ECSDA private key - */ - console.log(`\nExample 1: \n`); - const privateKey = PrivateKey.generateECDSA(); - console.log(`Private key: ${privateKey.toStringDer()}`); - - /** - * Step 2 - * - * Get the ECDSA public key - */ - const publicKey = privateKey.publicKey; - console.log(`Public key: ${publicKey.toStringDer()}`); - - /** - * Step 3 - * - * Use the `AccountCreateTransaction` and populate the `setAliasKey` field - */ - const accountCreateTx = new AccountCreateTransaction() - .setAliasKey(publicKey) - .freezeWith(client); - - /** - * Step 4 - * - * Sign the `AccountCreateTransaction` using an existing Hedera account and key to pay for the transaction fee - */ - const accountCreateTxSign = await accountCreateTx.sign(operatorKey); - - /** - * Step 5 - * - * Execute the transaction - */ - const accountCreateTxSubmit = await accountCreateTxSign.execute(client); - - /** - * Step 6 - * - * Return the Hedera account ID from the receipt of the transaction - */ - const newAccountId = ( - await accountCreateTxSubmit.getReceipt(client) - ).accountId.toString(); - console.log(`Account id of the new account: ${newAccountId}`); - - /** - * Step 7 - * - * Get the `AccountInfo` using the new account ID - */ - const accountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - - /** - * Step 8 - * - * Get the `AccountInfo` using the account public key in `0.0.aliasPublicKey` format - */ - const aliasPublicKey = publicKey.toAccountId(0, 0); - const accountInfoAlias = await new AccountInfoQuery() - .setAccountId(aliasPublicKey) - .execute(client); - - /** - * Step 9 - * - * Show the public key and the public key alias are the same on the account - */ - accountInfo.key.toString() === accountInfo.aliasKey.toString() && - accountInfo.aliasKey.toString() === accountInfoAlias.key.toString() && - accountInfoAlias.key.toString() === accountInfoAlias.aliasKey.toString() - ? console.log(`The public key and the public key alias are the same`) - : console.log(`The public key and the public key alias differ`); - - /** - * Step 10 - * - * Show this account has a corresponding EVM address in the mirror node - */ - - const link = `https://${process.env.HEDERA_NETWORK}.mirrornode.hedera.com/api/v1/accounts?account.id=${newAccountId}`; - try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access - let mirrorNodeAccountInfo = (await axios.get(link)).data.accounts[0]; - - // if the request does not succeed, wait for a bit and try again - // the mirror node needs some time to be up to date - while (mirrorNodeAccountInfo == undefined) { - await wait(5000); - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access - mirrorNodeAccountInfo = (await axios.get(link)).data.accounts[0]; - } - /**@type {string} */ - const mirrorNodeEvmAddress = mirrorNodeAccountInfo.evm_address; // eslint-disable-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access - - mirrorNodeEvmAddress !== null - ? console.log( - `The account has a corresponding EVM address in the mirror node: ${mirrorNodeEvmAddress}` - ) - : console.log( - `The EVM address of the account is missing in the mirror node` - ); - } catch (e) { - console.log(e); - } - - /** - * Example 2 - * - * Step 1 - * - * Create an ED25519 private key - */ - console.log(`\nExample 2: \n`); - const privateKey2 = PrivateKey.generateED25519(); - console.log(`Private key: ${privateKey2.toString()}`); - - /** - * Step 2 - * - * Get the ED25519 public key - */ - const publicKey2 = privateKey2.publicKey; - console.log(`Public key: ${publicKey2.toString()}`); - - /** - * Step 3 - * - * Use the `AccountCreateTransaction` and populate the `setAliasKey` field - */ - const accountCreateTx2 = new AccountCreateTransaction() - .setAliasKey(publicKey2) - .freezeWith(client); - - /** - * Step 4 - * - * Sign the `AccountCreateTransaction` using an existing Hedera account and key to pay for the transaction fee - */ - const accountCreateTxSign2 = await accountCreateTx2.sign(operatorKey); - - /** - * Step 5 - * - * Execute the transaction - */ - const accountCreateTxSubmit2 = await accountCreateTxSign2.execute(client); - - /** - * Step 6 - * - * Return the Hedera account ID from the receipt of the transaction - */ - const newAccountId2 = ( - await accountCreateTxSubmit2.getReceipt(client) - ).accountId.toString(); - console.log(`Account id of the new account: ${newAccountId2}`); - - /** - * Step 7 - * - * Get the `AccountInfo` using the new account ID - */ - const accountInfo2 = await new AccountInfoQuery() - .setAccountId(newAccountId2) - .execute(client); - - /** - * Step 8 - * - * Get the `AccountInfo` using the account public key in `0.0.aliasPublicKey` format - */ - const aliasPublicKey2 = publicKey2.toAccountId(0, 0); - const accountInfoAlias2 = await new AccountInfoQuery() - .setAccountId(aliasPublicKey2) - .execute(client); - - /** - * Step 9 - * - * Show the public key and the public key alias are the same on the account - */ - accountInfo2.key.toString() === accountInfo2.aliasKey.toString() && - accountInfo2.aliasKey.toString() === accountInfoAlias2.key.toString() && - accountInfoAlias2.key.toString() === accountInfoAlias2.aliasKey.toString() - ? console.log(`The public key and the public key alias are the same`) - : console.log(`The public key and the public key alias differ`); -} - -/** - * @param {number} timeout - * @returns {Promise} - */ -function wait(timeout) { - return new Promise((resolve) => { - setTimeout(resolve, timeout); - }); -} - -void main(); diff --git a/examples/lazy-create-account-tx.js b/examples/lazy-create-account-tx.js deleted file mode 100644 index 9eec7a464..000000000 --- a/examples/lazy-create-account-tx.js +++ /dev/null @@ -1,213 +0,0 @@ -import { - AccountId, - PrivateKey, - Client, - AccountInfoQuery, - AccountCreateTransaction, - TopicCreateTransaction, - Hbar, -} from "@hashgraph/sdk"; -import axios from "axios"; - -import dotenv from "dotenv"; - -dotenv.config(); - -/* -Lazy-create a new account using a public-address via the `AccountCreateTransaction` transaction. - -Reference: [HIP-583 Expand alias support in CryptoCreate & CryptoTransfer Transactions](https://hips.hedera.com/hip/hip-583) - -## Example 1: -- Create an ECSDA private key -- Extract the ECDSA public key -- Extract the Ethereum public address - - Add function in the SDK to calculate the Ethereum Address - - Ethereum account address / public-address - This is the rightmost 20 bytes of the 32 byte Keccak-256 hash of the ECDSA public key of the account. This calculation is in the manner described by the Ethereum Yellow Paper. -- Use the `AccountCreateTransaction` and populate `setEvmAddress(publicAddress)` field with the Ethereum public address -- Sign the `AccountCreateTransaction` transaction using an existing Hedera account and key to pay for the transaction fee -- The Hedera account that was created has a public address the user specified in the `AccountCreateTransaction` - - Will not have a Hedera account public key at this stage - - The account can only receive tokens or hbars - - This is referred to as a hollow account - - The alias property of the account will not have the public address -- Get the `AccountInfo` of the account and show that it is a hollow account i.e. does not have a public key -- To enhance the hollow account to have a public key the hollow account needs to be specified as a transaction fee payer in a HAPI transaction -- Any HAPI transaction can be used to apply the public key to the hollow account and create a complete Hedera account -- Use a HAPI transaction and set the hollow account as the transaction fee payer -- Sign with the ECDSA private key that corresponds to the public address on the hollow account -- Execute the transaction -- Get the `AccountInfo` and show that the account is now a complete account i.e. returns a public key of the account -*/ - -async function main() { - if (process.env.OPERATOR_ID == null || process.env.OPERATOR_KEY == null) { - throw new Error( - "Environment variables OPERATOR_ID, and OPERATOR_KEY are required." - ); - } - const operatorId = AccountId.fromString(process.env.OPERATOR_ID); - const operatorKey = PrivateKey.fromString(process.env.OPERATOR_KEY); - - const client = Client.forPreviewnet().setOperator(operatorId, operatorKey); - - /** - * Step 1 - * - * Create an ECSDA private key - */ - const privateKey = PrivateKey.generateECDSA(); - console.log(`Private key: ${privateKey.toStringDer()}`); - - /** - * Step 2 - * - * Extract the ECDSA public key - */ - const publicKey = privateKey.publicKey; - console.log(`Public key: ${publicKey.toStringDer()}`); - - /** - * - * Step 3 - * - * Extract the Ethereum public address - */ - const evmAddress = publicKey.toEvmAddress(); - console.log(`Account evm address: ${evmAddress}`); - - /** - * - * Step 4 - * - * Use the `AccountCreateTransaction` and populate `setEvmAddress(publicAddress)` field with the Ethereum public address - */ - const accountCreateTx = new AccountCreateTransaction() - .setEvmAddress(evmAddress) - .setInitialBalance(new Hbar(10)) - .freezeWith(client); - - /** - * - * Step 5 - * - * Sign the `AccountCreateTransaction` transaction using an existing Hedera account and key to pay for the transaction fee - */ - const accountCreateTxSign = await accountCreateTx.sign(operatorKey); - const accountCreateTxSubmit = await accountCreateTxSign.execute(client); - const newAccountId = ( - await accountCreateTxSubmit.getReceipt(client) - ).accountId.toString(); - - /** - * - * Step 6 - * - * Get the `AccountInfo` of the account and show that it is a hollow account i.e. does not have a public key - * - * The Hedera account that was created has a public address the user specified in the `AccountCreateTransaction` - * - Will not have a Hedera account public key at this stage - * - The account can only receive tokens or hbars - * - This is referred to as a hollow account - * - The alias property of the account will not have the public address - */ - const hollowAccountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - - console.log(`Check if it is a hollow account with 'AccountInfoQuery'`); - hollowAccountInfo.aliasKey === null && - hollowAccountInfo.key._toProtobufKey().keyList.keys.length == 0 && - hollowAccountInfo.contractAccountId !== null - ? console.log(`The newly created account is a hollow account`) - : console.log(`Not a hollow account`); - - // check the mirror node if the account is indeed a hollow account - const link = `https://${process.env.HEDERA_NETWORK}.mirrornode.hedera.com/api/v1/accounts?account.id=${newAccountId}`; - try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access - let mirrorNodeAccountInfo = (await axios.get(link)).data.accounts[0]; - - // if the request does not succeed, wait for a bit and try again - // the mirror node needs some time to be up to date - while (mirrorNodeAccountInfo == undefined) { - await wait(5000); - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access - mirrorNodeAccountInfo = (await axios.get(link)).data.accounts[0]; - } - - console.log(`Check in the mirror node if it is a hollow account`); - - mirrorNodeAccountInfo.alias === null && // eslint-disable-line @typescript-eslint/no-unsafe-member-access - mirrorNodeAccountInfo.key === null && // eslint-disable-line @typescript-eslint/no-unsafe-member-access - mirrorNodeAccountInfo.evm_address !== null // eslint-disable-line @typescript-eslint/no-unsafe-member-access - ? console.log(`The newly created account is a hollow account`) - : console.log(`Not a hollow account`); - } catch (e) { - console.log(e); - } - /** - * - * Step 7 - * - * Use a HAPI transaction and set the hollow account as the transaction fee payer - * - To enhance the hollow account to have a public key the hollow account needs to be specified as a transaction fee payer in a HAPI transaction - * - Any HAPI transaction can be used to apply the public key to the hollow account and create a complete Hedera account - */ - - // set the accound id of the hollow account and its private key as an operator - // in order to be a transaction fee payer in a HAPI transaction - client.setOperator(newAccountId, privateKey); - - let transaction = new TopicCreateTransaction() - .setTopicMemo("HIP-583") - .freezeWith(client); - - /** - * - * Step 8 - * - * Sign with the ECDSA private key that corresponds to the public address on the hollow account - */ - const transactionSign = await transaction.sign(privateKey); - - /** - * - * Step 9 - * - * Execute the transaction - */ - const transactionSubmit = await transactionSign.execute(client); - const status = ( - await transactionSubmit.getReceipt(client) - ).status.toString(); - console.log(`HAPI transaction status: ${status}`); - - /** - * - * Step 10 - * - * Get the `AccountInfo` and show that the account is now a complete account i.e. returns a public key of the account - */ - const completeAccountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - - completeAccountInfo.key !== null - ? console.log( - `The public key of the newly created and now complete account: ${completeAccountInfo.key.toString()}` - ) - : console.log(`Account ${newAccountId} is still a hollow account`); -} - -/** - * @param {number} timeout - * @returns {Promise} - */ -function wait(timeout) { - return new Promise((resolve) => { - setTimeout(resolve, timeout); - }); -} - -void main(); diff --git a/examples/lazy-create-transfer-tx.js b/examples/lazy-create-transfer-tx.js deleted file mode 100644 index f93a4fbb5..000000000 --- a/examples/lazy-create-transfer-tx.js +++ /dev/null @@ -1,186 +0,0 @@ -import { - AccountId, - PrivateKey, - Client, - TransferTransaction, - AccountInfoQuery, - TransactionReceiptQuery, - TopicCreateTransaction, -} from "@hashgraph/sdk"; - -import dotenv from "dotenv"; - -dotenv.config(); - -/* -Lazy-create a new account using a public-address via a `TransferTransaction`. - -Reference: [HIP-583 Expand alias support in CryptoCreate & CryptoTransfer Transactions](https://hips.hedera.com/hip/hip-583) - -## Example 2 -- Create an ECSDA private key -- Extract the ECDSA public key -- Extract the Ethereum public address - - Add function to calculate the Ethereum Address to in SDK - - Ethereum account address / public-address - This is the rightmost 20 bytes of the 32 byte Keccak-256 hash of the ECDSA public key of the account. This calculation is in the manner described by the Ethereum Yellow Paper. -- Use the `TransferTransaction` - - Populate the `FromAddress` with the sender Hedera AccountID - - Populate the `ToAddress` with Ethereum public address - - Note: Can transfer from public address to public address in the `TransferTransaction` for complete accounts. Transfers from hollow accounts will not work because the hollow account does not have a public key assigned to authorize transfers out of the account -- Sign the `TransferTransaction` transaction using an existing Hedera account and key paying for the transaction fee -- The `AccountCreateTransaction` is executed as a child transaction triggered by the `TransferTransaction` -- The Hedera Account that was created has a public address the user specified in the TransferTransaction ToAddress - - Will not have a public key at this stage - - Cannot do anything besides receive tokens or hbars - - The alias property of the account does not have the public address - - Referred to as a hollow account -- To get the new account ID ask for the child receipts or child records for the parent transaction ID of the `TransferTransaction` -- Get the `AccountInfo` and verify the account is a hollow account with the supplied public address (may need to verify with mirror node API) -- To enhance the hollow account to have a public key the hollow account needs to be specified as a transaction fee payer in a HAPI transaction -- Create a HAPI transaction and assign the new hollow account as the transaction fee payer -- Sign with the private key that corresponds to the public key on the hollow account -- Get the `AccountInfo` for the account and return the public key on the account to show it is a complete account -*/ - -async function main() { - if (process.env.OPERATOR_ID == null || process.env.OPERATOR_KEY == null) { - throw new Error( - "Environment variables OPERATOR_ID, and OPERATOR_KEY are required." - ); - } - const operatorId = AccountId.fromString(process.env.OPERATOR_ID); - const operatorKey = PrivateKey.fromString(process.env.OPERATOR_KEY); - - const client = Client.forPreviewnet().setOperator(operatorId, operatorKey); - - /** - * Step 1 - * - * Create an ECSDA private key - */ - const privateKey = PrivateKey.generateECDSA(); - console.log(`Private key: ${privateKey.toStringDer()}`); - - /** - * Step 2 - * - * Extract the ECDSA public key - */ - const publicKey = privateKey.publicKey; - console.log(`Public key: ${publicKey.toStringDer()}`); - - /** - * - * Step 3 - * - * Extract the Ethereum public address - */ - const evmAddress = publicKey.toEvmAddress(); - console.log(`New account ID: ${evmAddress}`); - - /** - * - * Step 4 - * - * Use the `TransferTransaction` - * - Populate the `FromAddress` with the sender Hedera AccountID - * - Populate the `ToAddress` with Ethereum public address - */ - const transferTx = new TransferTransaction() - .addHbarTransfer(operatorId, -10) - .addHbarTransfer(evmAddress, 10) - .freezeWith(client); - - /** - * - * Step 5 - * - * Sign the `TransferTransaction` transaction using an existing Hedera account and key paying for the transaction fee - */ - const transferTxSign = await transferTx.sign(operatorKey); - const transferTxSubmit = await transferTxSign.execute(client); - - /** - * - * Step 6 - * - * To get the new account ID ask for the child receipts or child records for the parent transaction ID of the `TransferTransaction` - * - The `AccountCreateTransaction` is executed as a child transaction triggered by the `TransferTransaction` - */ - const receipt = await new TransactionReceiptQuery() - .setTransactionId(transferTxSubmit.transactionId) - .setIncludeChildren(true) - .execute(client); - - const newAccountId = receipt.children[0].accountId.toString(); - console.log(`Account ID of the newly created account: ${newAccountId}`); - - /** - * - * Step 7 - * - * Get the `AccountInfo` and verify the account is a hollow account with the supplied public address - * - * The Hedera Account that was created has a public address the user specified in the TransferTransaction ToAddress - - Will not have a public key at this stage - - Cannot do anything besides receive tokens or hbars - - The alias property of the account does not have the public address - - Referred to as a hollow account - */ - const hollowAccountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - - console.log(`Check if it is a hollow account with 'AccountInfoQuery'`); - hollowAccountInfo.aliasKey === null && - hollowAccountInfo.key._toProtobufKey().keyList.keys.length == 0 && - hollowAccountInfo.contractAccountId !== null - ? console.log(`The newly created account is a hollow account`) - : console.log(`Not a hollow account`); - - /** - * - * Step 8 - * - * Create a HAPI transaction and assign the new hollow account as the transaction fee payer - * - To enhance the hollow account to have a public key the hollow account needs to be specified as a transaction fee payer in a HAPI transaction - */ - - // set the accound id of the hollow account and its private key as an operator - // in order to be a transaction fee payer in a HAPI transaction - client.setOperator(newAccountId, privateKey); - - let transaction = new TopicCreateTransaction() - .setTopicMemo("HIP-583") - .freezeWith(client); - - /** - * - * Step 9 - * - * Sign with the private key that corresponds to the public key on the hollow account - */ - const transactionSign = await transaction.sign(privateKey); - const transactionSubmit = await transactionSign.execute(client); - const status = ( - await transactionSubmit.getReceipt(client) - ).status.toString(); - console.log(`HAPI transaction status: ${status}`); - - /** - * - * Step 10 - * - * Get the `AccountInfo` for the account and return the public key on the account to show it is a complete account - */ - const completeAccountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - completeAccountInfo.key !== null - ? console.log( - `The public key of the newly created and now complete account: ${completeAccountInfo.key.toString()}` - ) - : console.log(`Account ${newAccountId} is still a hollow account`); -} - -void main(); diff --git a/examples/transfer-using-evm-address.js b/examples/transfer-using-evm-address.js deleted file mode 100644 index 919aea4cb..000000000 --- a/examples/transfer-using-evm-address.js +++ /dev/null @@ -1,159 +0,0 @@ -import { - AccountId, - PrivateKey, - Client, - TransferTransaction, - AccountInfoQuery, - TransactionReceiptQuery, - TopicCreateTransaction, -} from "@hashgraph/sdk"; - -import dotenv from "dotenv"; - -dotenv.config(); - -/* -Transfer HBAR or tokens to a Hedera account using their public-address. - -Reference: [HIP-583 Expand alias support in CryptoCreate & CryptoTransfer Transactions](https://hips.hedera.com/hip/hip-583) - -## Example 1 -- Create an ECSDA private key -- Extract the ECDSA public key -- Extract the Ethereum public address - - Add function to calculate the Ethereum Address to example in SDK - - Ethereum account address / public-address - This is the rightmost 20 bytes of the 32 byte Keccak-256 hash of the ECDSA public key of the account. This calculation is in the manner described by the Ethereum Yellow Paper. -- Transfer tokens using the `TransferTransaction` to the Etherum Account Address -- The From field should be a complete account that has a public address -- The To field should be to a public address (to create a new account) -- Get the child receipt or child record to return the Hedera Account ID for the new account that was created -- Get the `AccountInfo` on the new account and show it is a hollow account by not having a public key -- This is a hollow account in this state -- Use the hollow account as a transaction fee payer in a HAPI transaction -- Sign the transaction with ECDSA private key -- Get the `AccountInfo` of the account and show the account is now a complete account by returning the public key on the account -*/ - -async function main() { - if (process.env.OPERATOR_ID == null || process.env.OPERATOR_KEY == null) { - throw new Error( - "Environment variables OPERATOR_ID, and OPERATOR_KEY are required." - ); - } - const operatorId = AccountId.fromString(process.env.OPERATOR_ID); - const operatorKey = PrivateKey.fromString(process.env.OPERATOR_KEY); - - const client = Client.forPreviewnet().setOperator(operatorId, operatorKey); - - /** - * Step 1 - * - * Create an ECSDA private key - */ - const privateKey = PrivateKey.generateECDSA(); - console.log(`Private key: ${privateKey.toStringDer()}`); - - /** - * Step 2 - * - * Extract the ECDSA public key - */ - const publicKey = privateKey.publicKey; - console.log(`Public key: ${publicKey.toStringDer()}`); - - /** - * - * Step 3 - * - * Extract the Ethereum public address - */ - const evmAddress = publicKey.toEvmAddress(); - console.log(`Corresponding evm address: ${evmAddress}`); - - /** - * Step 4 - * - * Transfer tokens using the `TransferTransaction` to the Etherеum Account Address - * - The From field should be a complete account that has a public address - * - The To field should be to a public address (to create a new account) - */ - const transferTx = new TransferTransaction() - .addHbarTransfer(operatorId, -10) - .addHbarTransfer(evmAddress, 10) - .freezeWith(client); - - const transferTxSign = await transferTx.sign(operatorKey); - const transferTxSubmit = await transferTxSign.execute(client); - - /** - * Step 5 - * - * Get the child receipt or child record to return the Hedera Account ID for the new account that was created - */ - const receipt = await new TransactionReceiptQuery() - .setTransactionId(transferTxSubmit.transactionId) - .setIncludeChildren(true) - .execute(client); - - const newAccountId = receipt.children[0].accountId.toString(); - console.log(`Account ID of the newly created account: ${newAccountId}`); - - /** - * Step 6 - * - * Get the `AccountInfo` on the new account and show it is a hollow account by not having a public key - */ - const hollowAccountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - - hollowAccountInfo.key._toProtobufKey().keyList.keys.length == 0 - ? console.log( - `Account ${newAccountId} does not have public key, therefore it is a hollow account` - ) - : console.log( - `Account ${newAccountId} has a public key, therefore it is not a hollow account` - ); - - /** - * Step 7 - * - * Use the hollow account as a transaction fee payer in a HAPI transaction - */ - - // set the accound id of the hollow account and its private key as an operator - // in order to be a transaction fee payer in a HAPI transaction - client.setOperator(newAccountId, privateKey); - - let transaction = new TopicCreateTransaction() - .setTopicMemo("HIP-583") - .freezeWith(client); - - /** - * Step 8 - * - * Sign the transaction with ECDSA private key - */ - const transactionSign = await transaction.sign(privateKey); - const transactionSubmit = await transactionSign.execute(client); - const status = ( - await transactionSubmit.getReceipt(client) - ).status.toString(); - console.log(`HAPI transaction status: ${status}`); - - /** - * Step 9 - * - * Get the `AccountInfo` of the account and show the account is now a complete account by returning the public key on the account - */ - const completeAccountInfo = await new AccountInfoQuery() - .setAccountId(newAccountId) - .execute(client); - completeAccountInfo.key !== null - ? console.log( - `The public key of the newly created and now complete account: ${completeAccountInfo.key.toString()}` - ) - : console.log(`Account ${newAccountId} is still a hollow account`); -} - -void main(); diff --git a/package.json b/package.json index 387bcf149..0170a03e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hashgraph/sdk", - "version": "2.20.0-beta.4", + "version": "2.20.0", "description": "Hedera™ Hashgraph SDK", "types": "./lib/index.d.ts", "main": "./lib/index.cjs", @@ -53,8 +53,8 @@ "dependencies": { "@ethersproject/rlp": "^5.7.0", "@grpc/grpc-js": "^1.7.3", - "@hashgraph/cryptography": "^1.4.2-beta.2", - "@hashgraph/proto": "2.11.2-beta.1", + "@hashgraph/cryptography": "^1.4.3", + "@hashgraph/proto": "2.12.0", "axios": "^1.3.1", "bignumber.js": "^9.1.1", "crypto-js": "^4.1.1", diff --git a/packages/cryptography/package.json b/packages/cryptography/package.json index b65de81ba..ea3997966 100644 --- a/packages/cryptography/package.json +++ b/packages/cryptography/package.json @@ -1,6 +1,6 @@ { "name": "@hashgraph/cryptography", - "version": "1.4.2-beta.2", + "version": "1.4.3", "description": "Cryptographic utilities and primitives for the Hedera™ Hashgraph SDK", "main": "./lib/index.cjs", "types": "./lib/index.d.ts", diff --git a/packages/proto/package.json b/packages/proto/package.json index 48c115ca2..a9ae57519 100644 --- a/packages/proto/package.json +++ b/packages/proto/package.json @@ -1,6 +1,6 @@ { "name": "@hashgraph/proto", - "version": "2.11.2-beta.1", + "version": "2.12.0", "description": "Protobufs for the Hedera™ Hashgraph SDK", "main": "lib/index.js", "browser": "src/index.js", diff --git a/packages/proto/src/proto b/packages/proto/src/proto index 984d75d06..3fa0f5e6e 160000 --- a/packages/proto/src/proto +++ b/packages/proto/src/proto @@ -1 +1 @@ -Subproject commit 984d75d06219b0073faa20ef83a90b2aa6664448 +Subproject commit 3fa0f5e6e3d30f5945410fdedaddf8c7064b5911 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d0e35d431..c14da6a86 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,8 +10,8 @@ specifiers: '@ethersproject/rlp': ^5.7.0 '@grpc/grpc-js': ^1.7.3 '@grpc/proto-loader': ^0.7.4 - '@hashgraph/cryptography': ^1.4.2-beta.2 - '@hashgraph/proto': 2.11.2-beta.1 + '@hashgraph/cryptography': ^1.4.3 + '@hashgraph/proto': 2.12.0 '@playwright/test': ^1.30.0 '@types/chai': ^4.3.4 '@types/crypto-js': ^4.1.1 @@ -61,8 +61,8 @@ specifiers: dependencies: '@ethersproject/rlp': 5.7.0 '@grpc/grpc-js': 1.7.3 - '@hashgraph/cryptography': 1.4.2_expo@47.0.13 - '@hashgraph/proto': 2.11.2-beta.1 + '@hashgraph/cryptography': 1.4.3_expo@47.0.13 + '@hashgraph/proto': 2.12.0 axios: 1.3.1 bignumber.js: 9.1.1 crypto-js: 4.1.1 @@ -1936,8 +1936,8 @@ packages: protobufjs: 7.1.2 yargs: 16.2.0 - /@hashgraph/cryptography/1.4.2_expo@47.0.13: - resolution: {integrity: sha512-9p9wZvB7JQ7sgcllVHOQb8qxVvkYVfH4TjDsNiy/V38WOXNdf9L8CMd/A3zFP+eXm9jtrybqxmtLZHVO2XZ2lA==} + /@hashgraph/cryptography/1.4.3_expo@47.0.13: + resolution: {integrity: sha512-txU2SVz8mBJ5aHqkrIpmaerJSu0F/S9T/0eXpYAIC2USy/8oTisp54gKVDTETFdnCrq0tNgCJmWt2N8QHMMbcw==} engines: {node: '>=12.0.0'} peerDependencies: expo: ^45.0.3 @@ -1960,8 +1960,8 @@ packages: utf8: 3.0.0 dev: false - /@hashgraph/proto/2.11.2-beta.1: - resolution: {integrity: sha512-6HSCsNlnDEuLXGmBGNoLXUJE8/PaEknsZlUPGNvVjbKPMXU/ZgscZQ9UNdPLoMTxZcbgLwztxLxjhBbmpdG/eQ==} + /@hashgraph/proto/2.12.0: + resolution: {integrity: sha512-IIN6K3b2X8ih7V14IDH8rsVJ1DE9ud25FfKUpr+lDNnQdBfdZdG2AGlHRhc9iDAz4vCHoHc6F3Ao6yYKMceeTg==} engines: {node: '>=10.0.0'} dependencies: long: 4.0.0 diff --git a/src/EthereumFlow.js b/src/EthereumFlow.js index 2e389199d..3f89562cd 100644 --- a/src/EthereumFlow.js +++ b/src/EthereumFlow.js @@ -84,6 +84,24 @@ export default class EthereumFlow { if (props.maxGasAllowance != null) { this.setMaxGasAllowanceHbar(props.maxGasAllowance); } + + this._maxChunks = null; + } + + /** + * @returns {number | null} + */ + get maxChunks() { + return this._maxChunks; + } + + /** + * @param {number} maxChunks + * @returns {this} + */ + setMaxChunks(maxChunks) { + this._maxChunks = maxChunks; + return this; } /** @@ -177,14 +195,15 @@ export default class EthereumFlow { } ethereumTransaction - .setEthereumData(this._ethereumData.toBytes()) + .setEthereumData(ethereumTransactionDataBytes) .setCallDataFileId(this._callDataFileId); } else if (ethereumTransactionDataBytes.length <= 5120) { ethereumTransaction.setEthereumData(ethereumTransactionDataBytes); } else { const fileId = await createFile( this._ethereumData.callData, - client + client, + this._maxChunks ); this._ethereumData.callData = new Uint8Array(); @@ -203,9 +222,10 @@ export default class EthereumFlow { * @template MirrorChannelT * @param {Uint8Array} callData * @param {import("./client/Client.js").default} client + * @param {?number} maxChunks * @returns {Promise} */ -async function createFile(callData, client) { +async function createFile(callData, client, maxChunks) { const hexedCallData = hex.encode(callData); const fileId = /** @type {FileId} */ ( @@ -224,15 +244,14 @@ async function createFile(callData, client) { ); if (callData.length > 4096) { - await ( - await new FileAppendTransaction() - .setFileId(fileId) - .setContents( - hexedCallData.substring(4096, hexedCallData.length) - ) - .setChunkSize(4096) - .execute(client) - ).getReceipt(client); + let fileAppendTransaction = new FileAppendTransaction() + .setFileId(fileId) + .setContents(hexedCallData.substring(4096, hexedCallData.length)); + if (maxChunks != null) { + fileAppendTransaction.setMaxChunks(maxChunks); + } + + await (await fileAppendTransaction.execute(client)).getReceipt(client); } return fileId; diff --git a/src/PublicKey.js b/src/PublicKey.js index 036347053..c9bf98f3c 100644 --- a/src/PublicKey.js +++ b/src/PublicKey.js @@ -172,20 +172,12 @@ export default class PublicKey extends Key { } /** - * @deprecated Use `toEvmAddress()` instead. * @returns {string} */ toEthereumAddress() { return this._key.toEthereumAddress(); } - /** - * @returns {string} - */ - toEvmAddress() { - return this._key.toEthereumAddress(); - } - /** * @returns {string} */ diff --git a/src/Status.js b/src/Status.js index c07262c3c..e7639a413 100644 --- a/src/Status.js +++ b/src/Status.js @@ -621,6 +621,8 @@ export default class Status { return "TRANSACTION_HAS_UNKNOWN_FIELDS"; case Status.AccountIsImmutable: return "ACCOUNT_IS_IMMUTABLE"; + case Status.AliasAlreadyAssigned: + return "ALIAS_ALREADY_ASSIGNED"; default: return `UNKNOWN (${this._code})`; } @@ -1213,6 +1215,8 @@ export default class Status { return Status.TransactionHasUnknownFields; case 331: return Status.AccountIsImmutable; + case 332: + return Status.AliasAlreadyAssigned; default: throw new Error( `(BUG) Status.fromCode() does not handle code: ${code}` @@ -2719,3 +2723,8 @@ Status.TransactionHasUnknownFields = new Status(330); * The account cannot be modified. Account's key is not set */ Status.AccountIsImmutable = new Status(331); + +/** + * An alias that is assigned to an account or contract cannot be assigned to another account or contract. + */ +Status.AliasAlreadyAssigned = new Status(332); diff --git a/src/account/AccountAllowanceAdjustTransaction.js b/src/account/AccountAllowanceAdjustTransaction.js index 2a7d33104..02a262a25 100644 --- a/src/account/AccountAllowanceAdjustTransaction.js +++ b/src/account/AccountAllowanceAdjustTransaction.js @@ -306,6 +306,7 @@ export default class AccountAllowanceAdjustTransaction extends Transaction { serialNumbers: [nftId.serial], ownerAccountId: owner, allSerials: false, + delegatingSpender: null, }) ); } @@ -438,6 +439,7 @@ export default class AccountAllowanceAdjustTransaction extends Transaction { : spenderAccountId, serialNumbers: null, allSerials, + delegatingSpender: null, }) ); diff --git a/src/account/AccountAllowanceApproveTransaction.js b/src/account/AccountAllowanceApproveTransaction.js index fdebb1733..09ca9e043 100644 --- a/src/account/AccountAllowanceApproveTransaction.js +++ b/src/account/AccountAllowanceApproveTransaction.js @@ -163,7 +163,7 @@ export default class AccountAllowanceApproveTransaction extends Transaction { } /** - * @deprecated + * @deprecated - Use `approveHbarAllowance()` instead * @param {AccountId | string} spenderAccountId * @param {number | string | Long | LongObject | BigNumber | Hbar} amount * @returns {AccountAllowanceApproveTransaction} @@ -227,7 +227,7 @@ export default class AccountAllowanceApproveTransaction extends Transaction { } /** - * @deprecated + * @deprecated - Use `approveTokenAllowance()` instead * @param {TokenId | string} tokenId * @param {AccountId | string} spenderAccountId * @param {Long | number} amount @@ -258,13 +258,18 @@ export default class AccountAllowanceApproveTransaction extends Transaction { } /** - * @deprecated + * @deprecated - Use `approveTokenNftAllowance()` instead * @param {NftId | string} nftId * @param {AccountId | string} spenderAccountId * @returns {AccountAllowanceApproveTransaction} */ addTokenNftAllowance(nftId, spenderAccountId) { - return this._approveTokenNftAllowance(nftId, null, spenderAccountId); + return this._approveTokenNftAllowance( + nftId, + null, + spenderAccountId, + null + ); } /** @@ -278,9 +283,15 @@ export default class AccountAllowanceApproveTransaction extends Transaction { * @param {NftId | string} nftId * @param {AccountId | string | null} ownerAccountId * @param {AccountId | string} spenderAccountId + * @param {AccountId | string | null} delegatingSpender * @returns {AccountAllowanceApproveTransaction} */ - _approveTokenNftAllowance(nftId, ownerAccountId, spenderAccountId) { + _approveTokenNftAllowance( + nftId, + ownerAccountId, + spenderAccountId, + delegatingSpender + ) { this._requireNotFrozen(); const id = typeof nftId === "string" ? NftId.fromString(nftId) : nftId; @@ -308,16 +319,17 @@ export default class AccountAllowanceApproveTransaction extends Transaction { this._nftApprovals.push( new TokenNftAllowance({ tokenId: id.tokenId, - spenderAccountId: - typeof spenderAccountId === "string" - ? AccountId.fromString(spenderAccountId) - : spenderAccountId, + spenderAccountId: spender, ownerAccountId: typeof ownerAccountId === "string" ? AccountId.fromString(ownerAccountId) : ownerAccountId, serialNumbers: [id.serial], allSerials: false, + delegatingSpender: + typeof delegatingSpender === "string" + ? AccountId.fromString(delegatingSpender) + : delegatingSpender, }) ); } @@ -335,7 +347,29 @@ export default class AccountAllowanceApproveTransaction extends Transaction { return this._approveTokenNftAllowance( nftId, ownerAccountId, - spenderAccountId + spenderAccountId, + null + ); + } + + /** + * @param {NftId | string} nftId + * @param {AccountId | string} ownerAccountId + * @param {AccountId | string} spenderAccountId + * @param {AccountId | string} delegatingSpender + * @returns {AccountAllowanceApproveTransaction} + */ + approveTokenNftAllowanceWithDelegatingSpender( + nftId, + ownerAccountId, + spenderAccountId, + delegatingSpender + ) { + return this._approveTokenNftAllowance( + nftId, + ownerAccountId, + spenderAccountId, + delegatingSpender ); } @@ -370,6 +404,7 @@ export default class AccountAllowanceApproveTransaction extends Transaction { : ownerAccountId, serialNumbers: null, allSerials, + delegatingSpender: null, }) ); @@ -377,7 +412,7 @@ export default class AccountAllowanceApproveTransaction extends Transaction { } /** - * @deprecated + * @deprecated - Use `approveTokenNftAllowanceAllSerials()` instead * @param {TokenId | string} tokenId * @param {AccountId | string} ownerAccountId * @param {AccountId | string} spenderAccountId @@ -411,6 +446,25 @@ export default class AccountAllowanceApproveTransaction extends Transaction { ); } + /** + * @param {TokenId | string} tokenId + * @param {AccountId | string} ownerAccountId + * @param {AccountId | string} spenderAccountId + * @returns {AccountAllowanceApproveTransaction} + */ + deleteTokenNftAllowanceAllSerials( + tokenId, + ownerAccountId, + spenderAccountId + ) { + return this._approveAllTokenNftAllowance( + tokenId, + ownerAccountId, + spenderAccountId, + false + ); + } + /** * @param {Client} client */ diff --git a/src/account/AccountAllowanceDeleteTransaction.js b/src/account/AccountAllowanceDeleteTransaction.js index c7ee3814a..44037ca77 100644 --- a/src/account/AccountAllowanceDeleteTransaction.js +++ b/src/account/AccountAllowanceDeleteTransaction.js @@ -114,6 +114,8 @@ export default class AccountAllowanceDeleteTransaction extends Transaction { } /** + * @description If you want to remove allowance for all serials of a NFT + * - use AccountAllowanceApproveTransaction().deleteTokenNftAllowanceAllSerials() * @param {NftId | string} nftId * @param {AccountId | string} ownerAccountId * @returns {AccountAllowanceDeleteTransaction} @@ -147,6 +149,7 @@ export default class AccountAllowanceDeleteTransaction extends Transaction { serialNumbers: [id.serial], ownerAccountId: owner, allSerials: false, + delegatingSpender: null, }) ); } diff --git a/src/account/AccountCreateTransaction.js b/src/account/AccountCreateTransaction.js index af537cbf7..638ff5e05 100644 --- a/src/account/AccountCreateTransaction.js +++ b/src/account/AccountCreateTransaction.js @@ -57,7 +57,7 @@ export default class AccountCreateTransaction extends Transaction { * @param {Long | number} [props.stakedNodeId] * @param {boolean} [props.declineStakingReward] * @param {PublicKey} [props.aliasKey] - * @param {EvmAddress} [props.evmAddress] + * @param {EvmAddress} [props.aliasEvmAddress] */ constructor(props = {}) { super(); @@ -144,7 +144,7 @@ export default class AccountCreateTransaction extends Transaction { * @private * @type {?EvmAddress} */ - this._evmAddress = null; + this._aliasEvmAddress = null; if (props.key != null) { this.setKey(props.key); @@ -193,8 +193,8 @@ export default class AccountCreateTransaction extends Transaction { this.setAliasKey(props.aliasKey); } - if (props.evmAddress != null) { - this.setEvmAddress(props.evmAddress.toString()); + if (props.aliasEvmAddress != null) { + this.setAliasEvmAddress(props.aliasEvmAddress); } } @@ -221,21 +221,21 @@ export default class AccountCreateTransaction extends Transaction { ); let aliasKey = undefined; - let evmAddress = undefined; + let aliasEvmAddress = undefined; if (create.alias != null && create.alias.length > 0) { - aliasKey = Key._fromProtobufKey( - HashgraphProto.proto.Key.decode(create.alias) - ); + if (create.alias.length === 20) { + aliasEvmAddress = EvmAddress.fromBytes(create.alias); + } else { + aliasKey = Key._fromProtobufKey( + HashgraphProto.proto.Key.decode(create.alias) + ); + } } if (!(aliasKey instanceof PublicKey)) { aliasKey = undefined; } - if (create.evmAddress != null) { - evmAddress = EvmAddress.fromBytes(create.evmAddress); - } - return Transaction._fromProtobufTransactions( new AccountCreateTransaction({ key: @@ -279,7 +279,7 @@ export default class AccountCreateTransaction extends Transaction { : undefined, declineStakingReward: create.declineReward == true, aliasKey, - evmAddress, + aliasEvmAddress, }), transactions, signedTransactions, @@ -522,36 +522,21 @@ export default class AccountCreateTransaction extends Transaction { * @returns {?EvmAddress} */ get aliasEvmAddress() { - return this._evmAddress; + return this._aliasEvmAddress; } /** - * @deprecated - Use `setEvmAddress()` instead. The new `setEvmAddress()` method accepts only evm address as a hex format string + * @beta - Please note this is a beta feature and it's implementation is subject to change * @param {Uint8Array | string | EvmAddress} aliasEvmAddress * @returns {this} */ setAliasEvmAddress(aliasEvmAddress) { if (typeof aliasEvmAddress === "string") { - this._evmAddress = EvmAddress.fromString(aliasEvmAddress); + this._aliasEvmAddress = EvmAddress.fromString(aliasEvmAddress); } else if (aliasEvmAddress instanceof Uint8Array) { - this._evmAddress = EvmAddress.fromBytes(aliasEvmAddress); - } else { - this._evmAddress = aliasEvmAddress; - } - - return this; - } - - /** - * @param {string} evmAddress - * @returns {this} - */ - setEvmAddress(evmAddress) { - if (typeof evmAddress === "string") { - this._evmAddress = EvmAddress.fromString(evmAddress); + this._aliasEvmAddress = EvmAddress.fromBytes(aliasEvmAddress); } else { - // eslint-disable-next-line deprecation/deprecation - return this.setAliasEvmAddress(evmAddress); + this._aliasEvmAddress = aliasEvmAddress; } return this; @@ -593,15 +578,12 @@ export default class AccountCreateTransaction extends Transaction { */ _makeTransactionData() { let alias = null; - let evmAddress = null; if (this._aliasKey != null) { alias = HashgraphProto.proto.Key.encode( this._aliasKey._toProtobufKey() ).finish(); - } - - if (this._evmAddress != null) { - evmAddress = this._evmAddress.toBytes(); + } else if (this._aliasEvmAddress != null) { + alias = this._aliasEvmAddress.toBytes(); } return { @@ -630,7 +612,6 @@ export default class AccountCreateTransaction extends Transaction { stakedNodeId: this.stakedNodeId, declineReward: this.declineStakingRewards, alias, - evmAddress, }; } diff --git a/src/account/AccountId.js b/src/account/AccountId.js index 331faaf9f..bf4f68f90 100644 --- a/src/account/AccountId.js +++ b/src/account/AccountId.js @@ -39,16 +39,16 @@ export default class AccountId { * @param {(number | Long)=} realm * @param {(number | Long)=} num * @param {(PublicKey)=} aliasKey - * @param {(EvmAddress)=} evmAddress + * @param {(EvmAddress)=} aliasEvmAddress */ - constructor(props, realm, num, aliasKey, evmAddress) { + constructor(props, realm, num, aliasKey, aliasEvmAddress) { const result = entity_id.constructor(props, realm, num); this.shard = result.shard; this.realm = result.realm; this.num = result.num; this.aliasKey = aliasKey != null ? aliasKey : null; - this.evmAddress = evmAddress != null ? evmAddress : null; + this.aliasEvmAddress = aliasEvmAddress != null ? aliasEvmAddress : null; /** * @type {string | null} @@ -57,43 +57,34 @@ export default class AccountId { } /** - * @description Accepts the following formats as string: - * - as stand alone nubmers - * - as shard.realm.num - * - as shard.realm.hex (wo 0x prefix) - * - hex (w/wo 0x prefix) * @param {string} text * @returns {AccountId} */ static fromString(text) { - let shard = Long.ZERO; - let realm = Long.ZERO; - let num = Long.ZERO; - let aliasKey = undefined; - let evmAddress = undefined; + const result = entity_id.fromStringSplitter(text); - if ((text.startsWith("0x") && text.length == 42) || text.length == 40) { - evmAddress = EvmAddress.fromString(text); - } else { - const result = entity_id.fromStringSplitter(text); + if (Number.isNaN(result.shard) || Number.isNaN(result.realm)) { + throw new Error("invalid format for entity ID"); + } - if (Number.isNaN(result.shard) || Number.isNaN(result.realm)) { - throw new Error("invalid format for entity ID"); - } + const shard = + result.shard != null ? Long.fromString(result.shard) : Long.ZERO; + const realm = + result.realm != null ? Long.fromString(result.realm) : Long.ZERO; - if (result.shard != null) shard = Long.fromString(result.shard); - if (result.realm != null) realm = Long.fromString(result.realm); + let num = Long.ZERO; + let aliasKey = undefined; + let aliasEvmAddress = undefined; - if (result.numOrHex.length < 20) { - num = Long.fromString(result.numOrHex); - } else if (result.numOrHex.length == 40) { - evmAddress = EvmAddress.fromString(result.numOrHex); - } else { - aliasKey = PublicKey.fromString(result.numOrHex); - } + if (result.numOrHex.length < 20) { + num = Long.fromString(result.numOrHex); + } else if (result.numOrHex.length == 40) { + aliasEvmAddress = EvmAddress.fromString(result.numOrHex); + } else { + aliasKey = PublicKey.fromString(result.numOrHex); } - return new AccountId(shard, realm, num, aliasKey, evmAddress); + return new AccountId(shard, realm, num, aliasKey, aliasEvmAddress); } /** @@ -114,15 +105,6 @@ export default class AccountId { ); } - /** - * @summary Accepts an evm address only as `EvmAddress` type - * @param {EvmAddress} evmAddress - * @returns {AccountId} - */ - static fromEvmPublicAddress(evmAddress) { - return new AccountId(0, 0, 0, undefined, evmAddress); - } - /** * @internal * @param {HashgraphProto.proto.IAccountID} id @@ -130,28 +112,27 @@ export default class AccountId { */ static _fromProtobuf(id) { let aliasKey = undefined; - let evmAddress = undefined; - + let aliasEvmAddress = undefined; if (id.alias != null) { - aliasKey = Key._fromProtobufKey( - HashgraphProto.proto.Key.decode(id.alias) - ); + if (id.alias.length === 20) { + aliasEvmAddress = EvmAddress.fromBytes(id.alias); + } else { + aliasKey = Key._fromProtobufKey( + HashgraphProto.proto.Key.decode(id.alias) + ); + } } if (!(aliasKey instanceof PublicKey)) { aliasKey = undefined; } - if (id.evmAddress != null) { - evmAddress = EvmAddress.fromBytes(id.evmAddress); - } - return new AccountId( id.shardNum != null ? id.shardNum : 0, id.realmNum != null ? id.realmNum : 0, id.accountNum != null ? id.accountNum : 0, aliasKey, - evmAddress + aliasEvmAddress ); } @@ -162,13 +143,6 @@ export default class AccountId { return this._checksum; } - /** - * @returns {?EvmAddress} - */ - getEvmAddress() { - return this.evmAddress; - } - /** * @deprecated - Use `validateChecksum` instead * @param {Client} client @@ -222,33 +196,28 @@ export default class AccountId { return entity_id.toSolidityAddress([this.shard, this.realm, this.num]); } - //TODO remove the comments after we get to HIP-631 /** * @internal * @returns {HashgraphProto.proto.IAccountID} */ _toProtobuf() { let alias = null; - //let evmAddress = null; - if (this.aliasKey != null) { alias = HashgraphProto.proto.Key.encode( this.aliasKey._toProtobufKey() ).finish(); - } else if (this.evmAddress != null) { - alias = this.evmAddress._bytes; + } else if (this.aliasEvmAddress != null) { + alias = this.aliasEvmAddress._bytes; } - /* if (this.evmAddress != null) { - evmAddress = this.evmAddress._bytes; - } */ - return { alias, - accountNum: this.aliasKey != null ? null : this.num, + accountNum: + this.aliasKey != null || this.aliasEvmAddress != null + ? null + : this.num, shardNum: this.shard, realmNum: this.realm, - //evmAddress, }; } @@ -269,8 +238,8 @@ export default class AccountId { if (this.aliasKey != null) { account = this.aliasKey.toString(); - } else if (this.evmAddress != null) { - account = this.evmAddress.toString(); + } else if (this.aliasEvmAddress != null) { + account = this.aliasEvmAddress.toString(); } return `${this.shard.toString()}.${this.realm.toString()}.${account}`; @@ -299,13 +268,16 @@ export default class AccountId { if (this.aliasKey != null && other.aliasKey != null) { account = this.aliasKey.equals(other.aliasKey); - } else if (this.evmAddress != null && other.evmAddress != null) { - account = this.evmAddress.equals(other.evmAddress); + } else if ( + this.aliasEvmAddress != null && + other.aliasEvmAddress != null + ) { + account = this.aliasEvmAddress.equals(other.aliasEvmAddress); } else if ( this.aliasKey == null && other.aliasKey == null && - this.evmAddress == null && - other.evmAddress == null + this.aliasEvmAddress == null && + other.aliasEvmAddress == null ) { account = this.num.eq(other.num); } @@ -322,7 +294,7 @@ export default class AccountId { const id = new AccountId(this); id._checksum = this._checksum; id.aliasKey = this.aliasKey; - id.evmAddress = this.evmAddress; + id.aliasEvmAddress = this.aliasEvmAddress; return id; } @@ -352,9 +324,12 @@ export default class AccountId { } else { return 0; } - } else if (this.evmAddress != null && other.evmAddress != null) { - const t = this.evmAddress.toString(); - const o = other.evmAddress.toString(); + } else if ( + this.aliasEvmAddress != null && + other.aliasEvmAddress != null + ) { + const t = this.aliasEvmAddress.toString(); + const o = other.aliasEvmAddress.toString(); if (t > o) { return 1; @@ -366,8 +341,8 @@ export default class AccountId { } else if ( this.aliasKey == null && other.aliasKey == null && - this.evmAddress == null && - other.evmAddress == null + this.aliasEvmAddress == null && + other.aliasEvmAddress == null ) { return this.num.compare(other.num); } else { diff --git a/src/account/TokenNftAllowance.js b/src/account/TokenNftAllowance.js index 17d152102..7e71303ab 100644 --- a/src/account/TokenNftAllowance.js +++ b/src/account/TokenNftAllowance.js @@ -44,6 +44,7 @@ export default class TokenNftAllowance { * @param {AccountId | null} props.ownerAccountId * @param {Long[] | null} props.serialNumbers * @param {boolean | null} props.allSerials + * @param {AccountId | null} props.delegatingSpender */ constructor(props) { /** @@ -81,6 +82,14 @@ export default class TokenNftAllowance { */ this.allSerials = props.allSerials; + /** + * The account ID of the spender who is granted approvedForAll allowance and granting + * approval on an NFT serial to another spender. + * + * @readonly + */ + this.delegatingSpender = props.delegatingSpender; + Object.freeze(this); } @@ -121,6 +130,14 @@ export default class TokenNftAllowance { ) : [], allSerials, + delegatingSpender: + allowance.delegatingSpender != null + ? AccountId._fromProtobuf( + /**@type {HashgraphProto.proto.IAccountID}*/ ( + allowance.delegatingSpender + ) + ) + : null, }); } @@ -143,6 +160,7 @@ export default class TokenNftAllowance { ownerAccountId, serialNumbers: [], allSerials: null, + delegatingSpender: null, }); } @@ -172,6 +190,7 @@ export default class TokenNftAllowance { ) : [], allSerials: null, + delegatingSpender: null, }); } @@ -193,6 +212,10 @@ export default class TokenNftAllowance { approvedForAll: this.serialNumbers == null ? { value: this.allSerials } : null, serialNumbers: this.serialNumbers, + delegatingSpender: + this.delegatingSpender != null + ? this.delegatingSpender._toProtobuf() + : null, }; } diff --git a/src/exports.js b/src/exports.js index 6df2aa202..2c60bb50f 100644 --- a/src/exports.js +++ b/src/exports.js @@ -76,6 +76,7 @@ export { default as EthereumFlow } from "./EthereumFlow.js"; export { default as ExchangeRate } from "./ExchangeRate.js"; export { default as ExchangeRates } from "./ExchangeRates.js"; export { default as Executable } from "./Executable.js"; +export { default as FeeAssessmentMethod } from "./token/FeeAssessmentMethod.js"; export { default as FeeComponents } from "./FeeComponents.js"; export { default as FeeData } from "./FeeData.js"; export { default as FeeDataType } from "./FeeDataType.js"; diff --git a/src/transaction/TransactionRecord.js b/src/transaction/TransactionRecord.js index a768dc053..1ff108069 100644 --- a/src/transaction/TransactionRecord.js +++ b/src/transaction/TransactionRecord.js @@ -33,7 +33,6 @@ import TokenAssocation from "../token/TokenAssociation.js"; import Key from "../Key.js"; import PublicKey from "../PublicKey.js"; import TokenTransfer from "../token/TokenTransfer.js"; -import EvmAddress from "../EvmAddress.js"; /** * @typedef {import("../token/TokenId.js").default} TokenId @@ -75,9 +74,8 @@ export default class TransactionRecord { * @param {TokenNftAllowance[]} props.nftAllowanceAdjustments * @param {?Uint8Array} props.ethereumHash * @param {Transfer[]} props.paidStakingRewards - * @param {?Uint8Array} props.prngBytes - * @param {?number} props.prngNumber - * @param {?EvmAddress} props.evmAddress + * @param {?Uint8Array} props.prngBytes; + * @param {?number} props.prngNumber; */ constructor(props) { /** @@ -265,14 +263,6 @@ export default class TransactionRecord { */ this.prngNumber = props.prngNumber; - /** - * The new default EVM address of the account created by this transaction. - * This field is populated only when the EVM address is not specified in the related transaction body. - * - * @readonly - */ - this.evmAddress = props.evmAddress; - Object.freeze(this); } @@ -395,8 +385,6 @@ export default class TransactionRecord { prngBytes: this.prngBytes, prngNumber: this.prngNumber != null ? this.prngNumber : null, - evmAddress: - this.evmAddress != null ? this.evmAddress.toBytes() : null, }, }; } @@ -534,10 +522,6 @@ export default class TransactionRecord { : [], prngBytes: record.prngBytes != null ? record.prngBytes : null, prngNumber: record.prngNumber != null ? record.prngNumber : null, - evmAddress: - record.evmAddress != null - ? EvmAddress.fromBytes(record.evmAddress) - : null, }); } diff --git a/test/integration/TokenWipeIntegrationTest.js b/test/integration/TokenWipeIntegrationTest.js index b6a2c16ae..714dd52ff 100644 --- a/test/integration/TokenWipeIntegrationTest.js +++ b/test/integration/TokenWipeIntegrationTest.js @@ -184,7 +184,7 @@ describe("TokenWipe", function () { } }); - it("should error when amount is not set", async function () { + it("should not error when amount is not set", async function () { this.timeout(120000); const operatorId = env.operatorId; diff --git a/test/unit/AccountAllowanceApproveTransaction.js b/test/unit/AccountAllowanceApproveTransaction.js index b69c6e39c..4924792ce 100644 --- a/test/unit/AccountAllowanceApproveTransaction.js +++ b/test/unit/AccountAllowanceApproveTransaction.js @@ -70,6 +70,7 @@ describe("AccountAllowanceApproveTransaction", function () { spender: spenderAccountId1._toProtobuf(), tokenId: tokenId2._toProtobuf(), approvedForAll: null, + delegatingSpender: null, }, { owner: ownerAccountId._toProtobuf(), @@ -77,6 +78,7 @@ describe("AccountAllowanceApproveTransaction", function () { spender: spenderAccountId2._toProtobuf(), tokenId: tokenId2._toProtobuf(), approvedForAll: null, + delegatingSpender: null, }, { owner: ownerAccountId._toProtobuf(), @@ -84,6 +86,7 @@ describe("AccountAllowanceApproveTransaction", function () { spender: spenderAccountId1._toProtobuf(), tokenId: tokenId1._toProtobuf(), approvedForAll: { value: true }, + delegatingSpender: null, }, ], tokenAllowances: [ diff --git a/test/unit/AccountCreateTransaction.js b/test/unit/AccountCreateTransaction.js index 55c3a4dac..ef6de276d 100644 --- a/test/unit/AccountCreateTransaction.js +++ b/test/unit/AccountCreateTransaction.js @@ -51,7 +51,6 @@ describe("AccountCreateTransaction", function () { sendRecordThreshold: Long.fromString("9223372036854775807"), stakedAccountId: null, stakedNodeId: null, - evmAddress: new Uint8Array(), }); }); }); diff --git a/test/unit/EthereumFlowMocking.js b/test/unit/EthereumFlowMocking.js index 62bfddaa6..895f920ca 100644 --- a/test/unit/EthereumFlowMocking.js +++ b/test/unit/EthereumFlowMocking.js @@ -200,4 +200,306 @@ describe("EthereumFlowMocking", function () { await new EthereumFlow().setEthereumData(encoded).execute(client) ).getReceipt(client); }); + + it("extracts the calldata if it's too large and try to deploy it by chunks, but thrown", async function () { + this.timeout(10000); + + const decoded = rlp.decode(bytes); + const longCallData = "0x" + "00".repeat(7000); + decoded[5] = longCallData; + const encoded = hex.decode(rlp.encode(decoded)); + decoded[5] = "0x"; + const encodedWithoutCallData = hex.decode(rlp.encode(decoded)); + + ({ client, servers } = await Mocker.withResponses([ + [ + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const fileCreate = transactionBody.fileCreate; + expect( + `0x${fileCreate.contents.toString()}` + ).to.deep.equal( + // includes 0x prefix + longCallData.substring(0, 4098) + ); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { + response: { + transactionGetReceipt: { + header: { + nodeTransactionPrecheckCode: + proto.ResponseCodeEnum.OK, + }, + receipt: { + status: proto.ResponseCodeEnum.SUCCESS, + fileID: callDataFileId._toProtobuf(), + }, + }, + }, + }, + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const fileAppend = transactionBody.fileAppend; + expect(fileAppend.contents.toString()).to.deep.equal( + longCallData.substring(4098, 8194) + ); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { + response: { + transactionGetReceipt: { + header: { + nodeTransactionPrecheckCode: + proto.ResponseCodeEnum.OK, + }, + receipt: { + status: proto.ResponseCodeEnum.SUCCESS, + fileID: callDataFileId._toProtobuf(), + }, + }, + }, + }, + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const fileAppend = transactionBody.fileAppend; + expect(fileAppend.contents.toString()).to.deep.equal( + longCallData.substring(8194, 12290) + ); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { + response: { + transactionGetReceipt: { + header: { + nodeTransactionPrecheckCode: + proto.ResponseCodeEnum.OK, + }, + receipt: { + status: proto.ResponseCodeEnum.SUCCESS, + fileID: callDataFileId._toProtobuf(), + }, + }, + }, + }, + // Yes, you need 4 receipt responses here. One happens in + // `FileAppendTransaction.executeAll()` in a loop, and the next + // is for `TransactionResponse.getReceipt()` + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const ethereumTransaction = + transactionBody.ethereumTransaction; + expect(ethereumTransaction.ethereumData).to.deep.equal( + encodedWithoutCallData + ); + expect( + FileId._fromProtobuf( + ethereumTransaction.callData + ).toString() + ).to.equal(callDataFileId.toString()); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + ], + ])); + + let error = null; + try { + await new EthereumFlow() + .setEthereumData(encoded) + .setMaxChunks(2) + .execute(client); + } catch (err) { + error = err; + } + expect(error).to.be.an("Error"); + }); + + it("extracts the calldata if it's too large and deploy it by the right amount of chunks", async function () { + this.timeout(10000); + + const decoded = rlp.decode(bytes); + const longCallData = "0x" + "00".repeat(7000); + decoded[5] = longCallData; + const encoded = hex.decode(rlp.encode(decoded)); + decoded[5] = "0x"; + const encodedWithoutCallData = hex.decode(rlp.encode(decoded)); + + ({ client, servers } = await Mocker.withResponses([ + [ + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const fileCreate = transactionBody.fileCreate; + expect( + `0x${fileCreate.contents.toString()}` + ).to.deep.equal( + // includes 0x prefix + longCallData.substring(0, 4098) + ); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { + response: { + transactionGetReceipt: { + header: { + nodeTransactionPrecheckCode: + proto.ResponseCodeEnum.OK, + }, + receipt: { + status: proto.ResponseCodeEnum.SUCCESS, + fileID: callDataFileId._toProtobuf(), + }, + }, + }, + }, + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const fileAppend = transactionBody.fileAppend; + expect(fileAppend.contents.toString()).to.deep.equal( + longCallData.substring(4098, 8194) + ); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { + response: { + transactionGetReceipt: { + header: { + nodeTransactionPrecheckCode: + proto.ResponseCodeEnum.OK, + }, + receipt: { + status: proto.ResponseCodeEnum.SUCCESS, + fileID: callDataFileId._toProtobuf(), + }, + }, + }, + }, + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const fileAppend = transactionBody.fileAppend; + expect(fileAppend.contents.toString()).to.deep.equal( + longCallData.substring(8194, 12290) + ); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { + response: { + transactionGetReceipt: { + header: { + nodeTransactionPrecheckCode: + proto.ResponseCodeEnum.OK, + }, + receipt: { + status: proto.ResponseCodeEnum.SUCCESS, + fileID: callDataFileId._toProtobuf(), + }, + }, + }, + }, + // Yes, you need 4 receipt responses here. One happens in + // `FileAppendTransaction.executeAll()` in a loop, and the next + // is for `TransactionResponse.getReceipt()` + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + { + call: (request) => { + const transactionBody = proto.TransactionBody.decode( + proto.SignedTransaction.decode( + request.signedTransactionBytes + ).bodyBytes + ); + + const ethereumTransaction = + transactionBody.ethereumTransaction; + expect(ethereumTransaction.ethereumData).to.deep.equal( + encodedWithoutCallData + ); + expect( + FileId._fromProtobuf( + ethereumTransaction.callData + ).toString() + ).to.equal(callDataFileId.toString()); + + return { response: TRANSACTION_RESPONSE_SUCCESS }; + }, + }, + { response: TRANSACTION_RECEIPT_SUCCESS_RESPONSE }, + ], + ])); + + await ( + await new EthereumFlow() + .setEthereumData(encoded) + .setMaxChunks(3) + .execute(client) + ).getReceipt(client); + }); }); diff --git a/test/unit/TokenNftAllowance.js b/test/unit/TokenNftAllowance.js index cd89a550e..d0f1ff47c 100644 --- a/test/unit/TokenNftAllowance.js +++ b/test/unit/TokenNftAllowance.js @@ -16,6 +16,7 @@ describe("TokenNftAllowance", function () { spenderAccountId, serialNumbers: [serial], allSerials: false, + delegatingSpender: null, }); expect(allowance._toProtobuf()).to.deep.equal({ @@ -24,6 +25,7 @@ describe("TokenNftAllowance", function () { spender: spenderAccountId._toProtobuf(), serialNumbers: [serial], approvedForAll: null, + delegatingSpender: null, }); }); @@ -38,6 +40,7 @@ describe("TokenNftAllowance", function () { spenderAccountId, serialNumbers: null, allSerials: true, + delegatingSpender: null, }); expect(allowance._toProtobuf()).to.deep.equal({ @@ -46,6 +49,7 @@ describe("TokenNftAllowance", function () { spender: spenderAccountId._toProtobuf(), serialNumbers: null, approvedForAll: { value: true }, + delegatingSpender: null, }); }); }); diff --git a/test/unit/TransactionRecord.js b/test/unit/TransactionRecord.js index 452da42f0..974fb80fc 100644 --- a/test/unit/TransactionRecord.js +++ b/test/unit/TransactionRecord.js @@ -4,7 +4,7 @@ import { TransactionRecord } from "../../src/index.js"; import * as hex from "../../src/encoding/hex.js"; const HEX_BYTES = - "1afe010a26081612070800100018de092a130a110801100c1a0b0880ae99a4ffffffffff013800420058001230cac44f2db045ba441f3fbc295217f2eb0f956293d28b3401578f6160e66f4e47ea87952d91c4b1cb5bda6447823b979a1a0c08f3fcb495061083d9be900322190a0c08e8fcb495061098f09cf20112070800100018850918002a0030bee8f013526c0a0f0a0608001000180510d0df820118000a0f0a0608001000186210f08dff1e18000a100a070800100018a00610def1ef0318000a100a070800100018a10610def1ef0318000a110a070800100018850910fbf8b7e10718000a110a070800100018de091080a8d6b90718008a0100aa0100"; + "1afb010a26081612070800100018de092a130a110801100c1a0b0880ae99a4ffffffffff013800420058001230cac44f2db045ba441f3fbc295217f2eb0f956293d28b3401578f6160e66f4e47ea87952d91c4b1cb5bda6447823b979a1a0c08f3fcb495061083d9be900322190a0c08e8fcb495061098f09cf20112070800100018850918002a0030bee8f013526c0a0f0a0608001000180510d0df820118000a0f0a0608001000186210f08dff1e18000a100a070800100018a00610def1ef0318000a100a070800100018a10610def1ef0318000a110a070800100018850910fbf8b7e10718000a110a070800100018de091080a8d6b90718008a0100"; describe("TransactionRecord", function () { it("[from|to]Bytes()", function () {