@ledgerhq/coin-hedera 1.13.0-nightly.2 → 1.13.0-nightly.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/.unimportedrc.json +1 -1
- package/CHANGELOG.md +26 -0
- package/jest.config.js +1 -1
- package/jest.integ.config.js +8 -0
- package/lib/api/index.d.ts +4 -0
- package/lib/api/index.d.ts.map +1 -0
- package/lib/api/index.js +119 -0
- package/lib/api/index.js.map +1 -0
- package/lib/bridge/broadcast.d.ts +1 -1
- package/lib/bridge/broadcast.d.ts.map +1 -1
- package/lib/bridge/broadcast.js +6 -9
- package/lib/bridge/broadcast.js.map +1 -1
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib/bridge/buildOptimisticOperation.js +14 -11
- package/lib/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib/bridge/createTransaction.d.ts +1 -1
- package/lib/bridge/createTransaction.d.ts.map +1 -1
- package/lib/bridge/createTransaction.js +2 -0
- package/lib/bridge/createTransaction.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib/bridge/estimateMaxSpendable.js +2 -2
- package/lib/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +11 -10
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/prepareTransaction.js +6 -5
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/signOperation.d.ts +1 -1
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +53 -14
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/synchronisation.d.ts.map +1 -1
- package/lib/bridge/synchronisation.js +24 -11
- package/lib/bridge/synchronisation.js.map +1 -1
- package/lib/bridge/utils.d.ts +3 -13
- package/lib/bridge/utils.d.ts.map +1 -1
- package/lib/bridge/utils.js +10 -119
- package/lib/bridge/utils.js.map +1 -1
- package/lib/config.d.ts +8 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +9 -0
- package/lib/config.js.map +1 -0
- package/lib/constants.d.ts +11 -8
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +17 -13
- package/lib/constants.js.map +1 -1
- package/lib/deviceTransactionConfig.d.ts +1 -1
- package/lib/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/deviceTransactionConfig.js +3 -3
- package/lib/deviceTransactionConfig.js.map +1 -1
- package/lib/logic/broadcast.d.ts +3 -0
- package/lib/logic/broadcast.d.ts.map +1 -0
- package/lib/logic/broadcast.js +11 -0
- package/lib/logic/broadcast.js.map +1 -0
- package/lib/logic/combine.d.ts +2 -0
- package/lib/logic/combine.d.ts.map +1 -0
- package/lib/logic/combine.js +19 -0
- package/lib/logic/combine.js.map +1 -0
- package/lib/logic/craftTransaction.d.ts +8 -0
- package/lib/logic/craftTransaction.d.ts.map +1 -0
- package/lib/logic/craftTransaction.js +107 -0
- package/lib/logic/craftTransaction.js.map +1 -0
- package/lib/logic/estimateFees.d.ts +5 -0
- package/lib/logic/estimateFees.d.ts.map +1 -0
- package/lib/logic/estimateFees.js +25 -0
- package/lib/logic/estimateFees.js.map +1 -0
- package/lib/logic/getAssetFromToken.d.ts +4 -0
- package/lib/logic/getAssetFromToken.d.ts.map +1 -0
- package/lib/logic/getAssetFromToken.js +14 -0
- package/lib/logic/getAssetFromToken.js.map +1 -0
- package/lib/logic/getBalance.d.ts +4 -0
- package/lib/logic/getBalance.d.ts.map +1 -0
- package/lib/logic/getBalance.js +36 -0
- package/lib/logic/getBalance.js.map +1 -0
- package/lib/logic/getTokenFromAsset.d.ts +4 -0
- package/lib/logic/getTokenFromAsset.d.ts.map +1 -0
- package/lib/logic/getTokenFromAsset.js +13 -0
- package/lib/logic/getTokenFromAsset.js.map +1 -0
- package/lib/logic/index.d.ts +10 -0
- package/lib/logic/index.d.ts.map +1 -0
- package/lib/logic/index.js +22 -0
- package/lib/logic/index.js.map +1 -0
- package/lib/logic/lastBlock.d.ts +12 -0
- package/lib/logic/lastBlock.d.ts.map +1 -0
- package/lib/logic/lastBlock.js +25 -0
- package/lib/logic/lastBlock.js.map +1 -0
- package/lib/logic/listOperations.d.ts +19 -0
- package/lib/logic/listOperations.d.ts.map +1 -0
- package/lib/logic/listOperations.js +179 -0
- package/lib/logic/listOperations.js.map +1 -0
- package/lib/logic/utils.d.ts +55 -0
- package/lib/logic/utils.d.ts.map +1 -0
- package/lib/logic/utils.js +197 -0
- package/lib/logic/utils.js.map +1 -0
- package/lib/network/api.d.ts +24 -0
- package/lib/network/api.d.ts.map +1 -0
- package/lib/network/api.js +119 -0
- package/lib/network/api.js.map +1 -0
- package/lib/network/rpc.d.ts +12 -0
- package/lib/network/rpc.d.ts.map +1 -0
- package/lib/network/rpc.js +22 -0
- package/lib/network/rpc.js.map +1 -0
- package/lib/{api → network}/utils.d.ts +1 -5
- package/lib/network/utils.d.ts.map +1 -0
- package/lib/network/utils.js +52 -0
- package/lib/network/utils.js.map +1 -0
- package/lib/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib/test/bridgeDatasetTest.js +5 -1
- package/lib/test/bridgeDatasetTest.js.map +1 -1
- package/lib/test/fixtures/account.fixture.d.ts +17 -0
- package/lib/test/fixtures/account.fixture.d.ts.map +1 -1
- package/lib/test/fixtures/account.fixture.js +18 -1
- package/lib/test/fixtures/account.fixture.js.map +1 -1
- package/lib/test/fixtures/currency.fixture.d.ts.map +1 -1
- package/lib/test/fixtures/currency.fixture.js +1 -1
- package/lib/test/fixtures/currency.fixture.js.map +1 -1
- package/lib/test/fixtures/mirror.fixture.d.ts +1 -1
- package/lib/test/fixtures/mirror.fixture.d.ts.map +1 -1
- package/lib/test/fixtures/network.fixture.d.ts +3 -0
- package/lib/test/fixtures/network.fixture.d.ts.map +1 -0
- package/lib/test/fixtures/network.fixture.js +9 -0
- package/lib/test/fixtures/network.fixture.js.map +1 -0
- package/lib/test/fixtures/transaction.fixture.d.ts.map +1 -1
- package/lib/test/fixtures/transaction.fixture.js +3 -0
- package/lib/test/fixtures/transaction.fixture.js.map +1 -1
- package/lib/transaction.d.ts +1 -1
- package/lib/transaction.d.ts.map +1 -1
- package/lib/transaction.js +35 -6
- package/lib/transaction.js.map +1 -1
- package/lib/types/alpaca.d.ts +3 -0
- package/lib/types/alpaca.d.ts.map +1 -0
- package/lib/{api/types.js → types/alpaca.js} +1 -1
- package/lib/types/alpaca.js.map +1 -0
- package/lib/types/bridge.d.ts +28 -9
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +2 -0
- package/lib/types/index.js.map +1 -1
- package/lib/{api/types.d.ts → types/mirror.d.ts} +21 -2
- package/lib/types/mirror.d.ts.map +1 -0
- package/lib/types/mirror.js +3 -0
- package/lib/types/mirror.js.map +1 -0
- package/lib-es/api/index.d.ts +4 -0
- package/lib-es/api/index.d.ts.map +1 -0
- package/lib-es/api/index.js +112 -0
- package/lib-es/api/index.js.map +1 -0
- package/lib-es/bridge/broadcast.d.ts +1 -1
- package/lib-es/bridge/broadcast.d.ts.map +1 -1
- package/lib-es/bridge/broadcast.js +4 -7
- package/lib-es/bridge/broadcast.js.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.js +12 -9
- package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib-es/bridge/createTransaction.d.ts +1 -1
- package/lib-es/bridge/createTransaction.d.ts.map +1 -1
- package/lib-es/bridge/createTransaction.js +2 -0
- package/lib-es/bridge/createTransaction.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.js +2 -2
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +7 -6
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +4 -3
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/signOperation.d.ts +1 -1
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +53 -14
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/synchronisation.d.ts.map +1 -1
- package/lib-es/bridge/synchronisation.js +24 -11
- package/lib-es/bridge/synchronisation.js.map +1 -1
- package/lib-es/bridge/utils.d.ts +3 -13
- package/lib-es/bridge/utils.d.ts.map +1 -1
- package/lib-es/bridge/utils.js +7 -113
- package/lib-es/bridge/utils.js.map +1 -1
- package/lib-es/config.d.ts +8 -0
- package/lib-es/config.d.ts.map +1 -0
- package/lib-es/config.js +4 -0
- package/lib-es/config.js.map +1 -0
- package/lib-es/constants.d.ts +11 -8
- package/lib-es/constants.d.ts.map +1 -1
- package/lib-es/constants.js +13 -9
- package/lib-es/constants.js.map +1 -1
- package/lib-es/deviceTransactionConfig.d.ts +1 -1
- package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
- package/lib-es/deviceTransactionConfig.js +1 -1
- package/lib-es/deviceTransactionConfig.js.map +1 -1
- package/lib-es/logic/broadcast.d.ts +3 -0
- package/lib-es/logic/broadcast.d.ts.map +1 -0
- package/lib-es/logic/broadcast.js +7 -0
- package/lib-es/logic/broadcast.js.map +1 -0
- package/lib-es/logic/combine.d.ts +2 -0
- package/lib-es/logic/combine.d.ts.map +1 -0
- package/lib-es/logic/combine.js +12 -0
- package/lib-es/logic/combine.js.map +1 -0
- package/lib-es/logic/craftTransaction.d.ts +8 -0
- package/lib-es/logic/craftTransaction.d.ts.map +1 -0
- package/lib-es/logic/craftTransaction.js +100 -0
- package/lib-es/logic/craftTransaction.js.map +1 -0
- package/lib-es/logic/estimateFees.d.ts +5 -0
- package/lib-es/logic/estimateFees.d.ts.map +1 -0
- package/lib-es/logic/estimateFees.js +18 -0
- package/lib-es/logic/estimateFees.js.map +1 -0
- package/lib-es/logic/getAssetFromToken.d.ts +4 -0
- package/lib-es/logic/getAssetFromToken.d.ts.map +1 -0
- package/lib-es/logic/getAssetFromToken.js +10 -0
- package/lib-es/logic/getAssetFromToken.js.map +1 -0
- package/lib-es/logic/getBalance.d.ts +4 -0
- package/lib-es/logic/getBalance.d.ts.map +1 -0
- package/lib-es/logic/getBalance.js +32 -0
- package/lib-es/logic/getBalance.js.map +1 -0
- package/lib-es/logic/getTokenFromAsset.d.ts +4 -0
- package/lib-es/logic/getTokenFromAsset.d.ts.map +1 -0
- package/lib-es/logic/getTokenFromAsset.js +9 -0
- package/lib-es/logic/getTokenFromAsset.js.map +1 -0
- package/lib-es/logic/index.d.ts +10 -0
- package/lib-es/logic/index.d.ts.map +1 -0
- package/lib-es/logic/index.js +10 -0
- package/lib-es/logic/index.js.map +1 -0
- package/lib-es/logic/lastBlock.d.ts +12 -0
- package/lib-es/logic/lastBlock.d.ts.map +1 -0
- package/lib-es/logic/lastBlock.js +21 -0
- package/lib-es/logic/lastBlock.js.map +1 -0
- package/lib-es/logic/listOperations.d.ts +19 -0
- package/lib-es/logic/listOperations.d.ts.map +1 -0
- package/lib-es/logic/listOperations.js +172 -0
- package/lib-es/logic/listOperations.js.map +1 -0
- package/lib-es/logic/utils.d.ts +55 -0
- package/lib-es/logic/utils.d.ts.map +1 -0
- package/lib-es/logic/utils.js +174 -0
- package/lib-es/logic/utils.js.map +1 -0
- package/lib-es/network/api.d.ts +24 -0
- package/lib-es/network/api.d.ts.map +1 -0
- package/lib-es/network/api.js +113 -0
- package/lib-es/network/api.js.map +1 -0
- package/lib-es/network/rpc.d.ts +12 -0
- package/lib-es/network/rpc.d.ts.map +1 -0
- package/lib-es/network/rpc.js +19 -0
- package/lib-es/network/rpc.js.map +1 -0
- package/lib-es/{api → network}/utils.d.ts +1 -5
- package/lib-es/network/utils.d.ts.map +1 -0
- package/lib-es/network/utils.js +45 -0
- package/lib-es/network/utils.js.map +1 -0
- package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib-es/test/bridgeDatasetTest.js +5 -1
- package/lib-es/test/bridgeDatasetTest.js.map +1 -1
- package/lib-es/test/fixtures/account.fixture.d.ts +17 -0
- package/lib-es/test/fixtures/account.fixture.d.ts.map +1 -1
- package/lib-es/test/fixtures/account.fixture.js +17 -0
- package/lib-es/test/fixtures/account.fixture.js.map +1 -1
- package/lib-es/test/fixtures/currency.fixture.d.ts.map +1 -1
- package/lib-es/test/fixtures/currency.fixture.js +1 -1
- package/lib-es/test/fixtures/currency.fixture.js.map +1 -1
- package/lib-es/test/fixtures/mirror.fixture.d.ts +1 -1
- package/lib-es/test/fixtures/mirror.fixture.d.ts.map +1 -1
- package/lib-es/test/fixtures/network.fixture.d.ts +3 -0
- package/lib-es/test/fixtures/network.fixture.d.ts.map +1 -0
- package/lib-es/test/fixtures/network.fixture.js +5 -0
- package/lib-es/test/fixtures/network.fixture.js.map +1 -0
- package/lib-es/test/fixtures/transaction.fixture.d.ts.map +1 -1
- package/lib-es/test/fixtures/transaction.fixture.js +3 -0
- package/lib-es/test/fixtures/transaction.fixture.js.map +1 -1
- package/lib-es/transaction.d.ts +1 -1
- package/lib-es/transaction.d.ts.map +1 -1
- package/lib-es/transaction.js +35 -6
- package/lib-es/transaction.js.map +1 -1
- package/lib-es/types/alpaca.d.ts +3 -0
- package/lib-es/types/alpaca.d.ts.map +1 -0
- package/lib-es/types/alpaca.js +2 -0
- package/lib-es/types/alpaca.js.map +1 -0
- package/lib-es/types/bridge.d.ts +28 -9
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/lib-es/types/index.d.ts +2 -0
- package/lib-es/types/index.d.ts.map +1 -1
- package/lib-es/types/index.js +2 -0
- package/lib-es/types/index.js.map +1 -1
- package/lib-es/{api/types.d.ts → types/mirror.d.ts} +21 -2
- package/lib-es/types/mirror.d.ts.map +1 -0
- package/lib-es/types/mirror.js +2 -0
- package/lib-es/types/mirror.js.map +1 -0
- package/package.json +8 -7
- package/src/api/index.integ.test.ts +401 -0
- package/src/api/index.test.ts +30 -0
- package/src/api/index.ts +149 -0
- package/src/bridge/broadcast.ts +5 -10
- package/src/bridge/buildOptimisticOperation.integration.test.ts +8 -8
- package/src/bridge/buildOptimisticOperation.ts +13 -10
- package/src/bridge/createTransaction.ts +3 -1
- package/src/bridge/estimateMaxSpendable.ts +6 -3
- package/src/bridge/getTransactionStatus.test.ts +11 -10
- package/src/bridge/getTransactionStatus.ts +12 -11
- package/src/bridge/js-estimateMaxSpendable.integration.test.ts +6 -3
- package/src/bridge/prepareTransaction.test.ts +9 -17
- package/src/bridge/prepareTransaction.ts +5 -4
- package/src/bridge/serialization.test.ts +6 -6
- package/src/bridge/signOperation.ts +69 -16
- package/src/bridge/synchronisation.ts +22 -14
- package/src/bridge/utils.integration.test.ts +25 -248
- package/src/bridge/utils.ts +14 -160
- package/src/config.ts +7 -0
- package/src/constants.ts +15 -9
- package/src/deviceTransactionConfig.ts +2 -2
- package/src/logic/broadcast.test.ts +58 -0
- package/src/logic/broadcast.ts +8 -0
- package/src/logic/combine.test.ts +119 -0
- package/src/logic/combine.ts +14 -0
- package/src/logic/craftTransaction.test.ts +215 -0
- package/src/logic/craftTransaction.ts +175 -0
- package/src/logic/estimateFees.test.ts +99 -0
- package/src/logic/estimateFees.ts +28 -0
- package/src/logic/getAssetFromToken.test.ts +27 -0
- package/src/logic/getAssetFromToken.ts +12 -0
- package/src/logic/getBalance.test.ts +200 -0
- package/src/logic/getBalance.ts +39 -0
- package/src/logic/getTokenFromAsset.test.ts +22 -0
- package/src/logic/getTokenFromAsset.ts +17 -0
- package/src/logic/index.ts +9 -0
- package/src/logic/lastBlock.test.ts +23 -0
- package/src/logic/lastBlock.ts +23 -0
- package/src/logic/listOperations.test.ts +388 -0
- package/src/logic/listOperations.ts +247 -0
- package/src/logic/utils.test.ts +432 -0
- package/src/logic/utils.ts +255 -0
- package/src/{api/mirror.test.ts → network/api.test.ts} +81 -35
- package/src/network/api.ts +159 -0
- package/src/network/rpc.test.ts +68 -0
- package/src/network/rpc.ts +25 -0
- package/src/network/utils.test.ts +175 -0
- package/src/network/utils.ts +58 -0
- package/src/test/bridgeDatasetTest.ts +6 -2
- package/src/test/fixtures/account.fixture.ts +18 -0
- package/src/test/fixtures/currency.fixture.ts +1 -1
- package/src/test/fixtures/mirror.fixture.ts +1 -1
- package/src/test/fixtures/network.fixture.ts +6 -0
- package/src/test/fixtures/transaction.fixture.ts +5 -2
- package/src/transaction.ts +40 -9
- package/src/types/alpaca.ts +3 -0
- package/src/types/bridge.ts +36 -10
- package/src/types/index.ts +2 -0
- package/src/{api/types.ts → types/mirror.ts} +23 -1
- package/lib/api/mirror.d.ts +0 -6
- package/lib/api/mirror.d.ts.map +0 -1
- package/lib/api/mirror.js +0 -84
- package/lib/api/mirror.js.map +0 -1
- package/lib/api/network.d.ts +0 -11
- package/lib/api/network.d.ts.map +0 -1
- package/lib/api/network.js +0 -80
- package/lib/api/network.js.map +0 -1
- package/lib/api/types.d.ts.map +0 -1
- package/lib/api/types.js.map +0 -1
- package/lib/api/utils.d.ts.map +0 -1
- package/lib/api/utils.js +0 -132
- package/lib/api/utils.js.map +0 -1
- package/lib/logic.d.ts +0 -11
- package/lib/logic.d.ts.map +0 -1
- package/lib/logic.js +0 -37
- package/lib/logic.js.map +0 -1
- package/lib-es/api/mirror.d.ts +0 -6
- package/lib-es/api/mirror.d.ts.map +0 -1
- package/lib-es/api/mirror.js +0 -74
- package/lib-es/api/mirror.js.map +0 -1
- package/lib-es/api/network.d.ts +0 -11
- package/lib-es/api/network.d.ts.map +0 -1
- package/lib-es/api/network.js +0 -71
- package/lib-es/api/network.js.map +0 -1
- package/lib-es/api/types.d.ts.map +0 -1
- package/lib-es/api/types.js +0 -2
- package/lib-es/api/types.js.map +0 -1
- package/lib-es/api/utils.d.ts.map +0 -1
- package/lib-es/api/utils.js +0 -124
- package/lib-es/api/utils.js.map +0 -1
- package/lib-es/logic.d.ts +0 -11
- package/lib-es/logic.d.ts.map +0 -1
- package/lib-es/logic.js +0 -29
- package/lib-es/logic.js.map +0 -1
- package/src/api/mirror.ts +0 -91
- package/src/api/network.test.ts +0 -49
- package/src/api/network.ts +0 -125
- package/src/api/utils.ts +0 -150
- package/src/logic.test.ts +0 -152
- package/src/logic.ts +0 -66
|
@@ -1,50 +1,42 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
-
import { InvalidAddress } from "@ledgerhq/errors";
|
|
3
|
-
import cvsApi from "@ledgerhq/live-countervalues/api/index";
|
|
4
2
|
import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account";
|
|
3
|
+
import { setCryptoAssetsStore } from "@ledgerhq/coin-framework/crypto-assets/index";
|
|
4
|
+
import { legacyCryptoAssetsStore } from "@ledgerhq/cryptoassets/tokens";
|
|
5
|
+
import { HEDERA_OPERATION_TYPES, HEDERA_TRANSACTION_MODES } from "../constants";
|
|
6
|
+
import { estimateFees } from "../logic/estimateFees";
|
|
5
7
|
import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
|
|
8
|
+
import {
|
|
9
|
+
getMockedCurrency,
|
|
10
|
+
getMockedTokenCurrency,
|
|
11
|
+
getTokenCurrencyFromCAL,
|
|
12
|
+
} from "../test/fixtures/currency.fixture";
|
|
6
13
|
import { getMockedTransaction } from "../test/fixtures/transaction.fixture";
|
|
14
|
+
import { getMockedOperation } from "../test/fixtures/operation.fixture";
|
|
15
|
+
import { getMockedMirrorToken } from "../test/fixtures/mirror.fixture";
|
|
16
|
+
import type { HederaOperationExtra } from "../types";
|
|
7
17
|
import {
|
|
8
18
|
applyPendingExtras,
|
|
9
19
|
calculateAmount,
|
|
10
|
-
checkAccountTokenAssociationStatus,
|
|
11
|
-
getCurrencyToUSDRate,
|
|
12
|
-
getEstimatedFees,
|
|
13
20
|
getSubAccounts,
|
|
14
21
|
getSyncHash,
|
|
15
22
|
mergeSubAccounts,
|
|
16
|
-
safeParseAccountId,
|
|
17
23
|
patchOperationWithExtra,
|
|
18
24
|
prepareOperations,
|
|
19
25
|
} from "./utils";
|
|
20
|
-
import {
|
|
21
|
-
getMockedCurrency,
|
|
22
|
-
getMockedTokenCurrency,
|
|
23
|
-
getTokenCurrencyFromCAL,
|
|
24
|
-
} from "../test/fixtures/currency.fixture";
|
|
25
|
-
import { getMockedOperation } from "../test/fixtures/operation.fixture";
|
|
26
|
-
import { HederaOperationExtra } from "../types";
|
|
27
|
-
import { getAccount } from "../api/mirror";
|
|
28
|
-
import { HederaRecipientInvalidChecksum } from "../errors";
|
|
29
|
-
import { isValidExtra } from "../logic";
|
|
30
|
-
import { getMockedMirrorToken } from "../test/fixtures/mirror.fixture";
|
|
31
|
-
import { HEDERA_OPERATION_TYPES, HEDERA_TRANSACTION_KINDS } from "../constants";
|
|
32
|
-
|
|
33
|
-
jest.mock("../api/mirror");
|
|
34
|
-
jest.mock("@ledgerhq/live-countervalues/api/index");
|
|
35
|
-
|
|
36
|
-
const mockedFetchLatest = cvsApi.fetchLatest as jest.MockedFunction<typeof cvsApi.fetchLatest>;
|
|
37
|
-
const mockedGetAccount = getAccount as jest.MockedFunction<typeof getAccount>;
|
|
38
26
|
|
|
39
27
|
describe("utils", () => {
|
|
28
|
+
beforeAll(() => {
|
|
29
|
+
setCryptoAssetsStore(legacyCryptoAssetsStore);
|
|
30
|
+
});
|
|
31
|
+
|
|
40
32
|
describe("calculateAmount", () => {
|
|
41
33
|
let estimatedFees: Record<"crypto" | "associate", BigNumber>;
|
|
42
34
|
|
|
43
35
|
beforeAll(async () => {
|
|
44
36
|
const mockedAccount = getMockedAccount();
|
|
45
37
|
const [crypto, associate] = await Promise.all([
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
estimateFees(mockedAccount.currency, HEDERA_OPERATION_TYPES.CryptoTransfer),
|
|
39
|
+
estimateFees(mockedAccount.currency, HEDERA_OPERATION_TYPES.TokenAssociate),
|
|
48
40
|
]);
|
|
49
41
|
|
|
50
42
|
estimatedFees = { crypto, associate };
|
|
@@ -131,8 +123,8 @@ describe("utils", () => {
|
|
|
131
123
|
const mockedTransaction = getMockedTransaction({
|
|
132
124
|
useAllAmount: false,
|
|
133
125
|
amount: new BigNumber(1),
|
|
126
|
+
mode: HEDERA_TRANSACTION_MODES.TokenAssociate,
|
|
134
127
|
properties: {
|
|
135
|
-
name: HEDERA_TRANSACTION_KINDS.TokenAssociate.name,
|
|
136
128
|
token: mockedTokenCurrency,
|
|
137
129
|
},
|
|
138
130
|
});
|
|
@@ -149,83 +141,6 @@ describe("utils", () => {
|
|
|
149
141
|
});
|
|
150
142
|
});
|
|
151
143
|
|
|
152
|
-
describe("getEstimatedFees", () => {
|
|
153
|
-
const mockedAccount = getMockedAccount();
|
|
154
|
-
|
|
155
|
-
beforeEach(() => {
|
|
156
|
-
jest.clearAllMocks();
|
|
157
|
-
// reset LRU cache to make sure all tests receive correct mocks from mockedFetchLatest
|
|
158
|
-
getCurrencyToUSDRate.clear(mockedAccount.currency.ticker);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test("returns estimated fee based on USD rate for CryptoTransfer", async () => {
|
|
162
|
-
// 1 HBAR = 1 USD
|
|
163
|
-
const usdRate = 1;
|
|
164
|
-
mockedFetchLatest.mockResolvedValueOnce([usdRate]);
|
|
165
|
-
|
|
166
|
-
const result = await getEstimatedFees(mockedAccount, HEDERA_OPERATION_TYPES.CryptoTransfer);
|
|
167
|
-
|
|
168
|
-
const baseFeeTinybar = 0.0001 * 10 ** 8;
|
|
169
|
-
const expectedFee = new BigNumber(baseFeeTinybar)
|
|
170
|
-
.div(usdRate)
|
|
171
|
-
.integerValue(BigNumber.ROUND_CEIL)
|
|
172
|
-
.multipliedBy(2); // safety rate
|
|
173
|
-
|
|
174
|
-
expect(result.toFixed()).toBe(expectedFee.toFixed());
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test("returns estimated fee based on USD rate for TokenTransfer", async () => {
|
|
178
|
-
// 1 HBAR = 0.5 USD
|
|
179
|
-
const usdRate = 0.5;
|
|
180
|
-
mockedFetchLatest.mockResolvedValueOnce([usdRate]);
|
|
181
|
-
|
|
182
|
-
const result = await getEstimatedFees(mockedAccount, HEDERA_OPERATION_TYPES.TokenTransfer);
|
|
183
|
-
|
|
184
|
-
const baseFeeTinybar = 0.001 * 10 ** 8;
|
|
185
|
-
const expectedFee = new BigNumber(baseFeeTinybar)
|
|
186
|
-
.div(usdRate)
|
|
187
|
-
.integerValue(BigNumber.ROUND_CEIL)
|
|
188
|
-
.multipliedBy(2);
|
|
189
|
-
|
|
190
|
-
expect(result.toFixed()).toBe(expectedFee.toFixed());
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
test("returns estimated fee based on USD rate for TokenAssociate", async () => {
|
|
194
|
-
// 1 HBAR = 2 USD
|
|
195
|
-
const usdRate = 2;
|
|
196
|
-
mockedFetchLatest.mockResolvedValueOnce([usdRate]);
|
|
197
|
-
|
|
198
|
-
const result = await getEstimatedFees(mockedAccount, HEDERA_OPERATION_TYPES.TokenAssociate);
|
|
199
|
-
|
|
200
|
-
const baseFeeTinybar = 0.05 * 10 ** 8;
|
|
201
|
-
const expectedFee = new BigNumber(baseFeeTinybar)
|
|
202
|
-
.div(usdRate)
|
|
203
|
-
.integerValue(BigNumber.ROUND_CEIL)
|
|
204
|
-
.multipliedBy(2);
|
|
205
|
-
|
|
206
|
-
expect(result.toFixed()).toBe(expectedFee.toFixed());
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
test("falls back to default estimate when cvs api returns null", async () => {
|
|
210
|
-
const usdRate = null;
|
|
211
|
-
mockedFetchLatest.mockResolvedValueOnce([usdRate]);
|
|
212
|
-
|
|
213
|
-
const result = await getEstimatedFees(mockedAccount, HEDERA_OPERATION_TYPES.CryptoTransfer);
|
|
214
|
-
|
|
215
|
-
const expected = new BigNumber("150200").multipliedBy(2);
|
|
216
|
-
expect(result.toFixed()).toBe(expected.toFixed());
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
test("falls back to default estimate on cvs api failure", async () => {
|
|
220
|
-
mockedFetchLatest.mockRejectedValueOnce(new Error("Network error"));
|
|
221
|
-
|
|
222
|
-
const result = await getEstimatedFees(mockedAccount, HEDERA_OPERATION_TYPES.CryptoTransfer);
|
|
223
|
-
|
|
224
|
-
const expected = new BigNumber("150200").multipliedBy(2);
|
|
225
|
-
expect(result.toFixed()).toBe(expected.toFixed());
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
|
|
229
144
|
describe("getSyncHash", () => {
|
|
230
145
|
const mockedCurrency = getMockedCurrency();
|
|
231
146
|
|
|
@@ -307,7 +222,7 @@ describe("utils", () => {
|
|
|
307
222
|
expect(result).toHaveLength(1);
|
|
308
223
|
expect(result[0].token).toEqual(tokenCurrencyFromCAL);
|
|
309
224
|
expect(result[0].operations).toHaveLength(0);
|
|
310
|
-
expect(result[0].balance
|
|
225
|
+
expect(result[0].balance).toEqual(new BigNumber(42));
|
|
311
226
|
});
|
|
312
227
|
});
|
|
313
228
|
|
|
@@ -322,7 +237,7 @@ describe("utils", () => {
|
|
|
322
237
|
accountId: encodeTokenAccountId(mockedTokenAccount.parentId, tokenCurrencyFromCAL),
|
|
323
238
|
});
|
|
324
239
|
|
|
325
|
-
const result = prepareOperations([mockedCoinOperation], [mockedTokenOperation]
|
|
240
|
+
const result = prepareOperations([mockedCoinOperation], [mockedTokenOperation]);
|
|
326
241
|
|
|
327
242
|
expect(result).toHaveLength(1);
|
|
328
243
|
expect(result[0].subOperations).toEqual([mockedTokenOperation]);
|
|
@@ -335,7 +250,7 @@ describe("utils", () => {
|
|
|
335
250
|
accountId: encodeTokenAccountId(mockedTokenAccount.parentId, tokenCurrencyFromCAL),
|
|
336
251
|
});
|
|
337
252
|
|
|
338
|
-
const result = prepareOperations([], [mockedOrphanTokenOperation]
|
|
253
|
+
const result = prepareOperations([], [mockedOrphanTokenOperation]);
|
|
339
254
|
const noneOp = result.find(op => op.type === "NONE");
|
|
340
255
|
|
|
341
256
|
expect(typeof noneOp).toBe("object");
|
|
@@ -343,42 +258,6 @@ describe("utils", () => {
|
|
|
343
258
|
expect(noneOp?.subOperations?.[0]).toEqual(mockedOrphanTokenOperation);
|
|
344
259
|
expect(noneOp?.hash).toBe("unknown-hash");
|
|
345
260
|
});
|
|
346
|
-
|
|
347
|
-
test("adds associatedTokenId to ASSOCIATE_TOKEN coin operation based on consensusTimestamp", () => {
|
|
348
|
-
const mockedCoinOperation = getMockedOperation({
|
|
349
|
-
type: "ASSOCIATE_TOKEN",
|
|
350
|
-
extra: { consensusTimestamp: "123" },
|
|
351
|
-
});
|
|
352
|
-
const mockedMirrorToken = getMockedMirrorToken({
|
|
353
|
-
token_id: "0.0.1001",
|
|
354
|
-
created_timestamp: "123",
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
const result = prepareOperations([mockedCoinOperation], [], [mockedMirrorToken]);
|
|
358
|
-
const extra = isValidExtra(result[0].extra) ? result[0].extra : null;
|
|
359
|
-
|
|
360
|
-
expect(typeof extra).toBe("object");
|
|
361
|
-
expect(extra).not.toBeNull();
|
|
362
|
-
expect(extra?.associatedTokenId).toBe("0.0.1001");
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
test("ignores enrichment of ASSOCIATE_TOKEN operation if consensusTimestamp mismatches", () => {
|
|
366
|
-
const mockedCoinOperation = getMockedOperation({
|
|
367
|
-
type: "ASSOCIATE_TOKEN",
|
|
368
|
-
extra: { consensusTimestamp: "123" },
|
|
369
|
-
});
|
|
370
|
-
const mockedMirrorToken = getMockedMirrorToken({
|
|
371
|
-
token_id: "0.0.1001",
|
|
372
|
-
created_timestamp: "999",
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
const result = prepareOperations([mockedCoinOperation], [], [mockedMirrorToken]);
|
|
376
|
-
const extra = isValidExtra(result[0].extra) ? result[0].extra : null;
|
|
377
|
-
|
|
378
|
-
expect(typeof extra).toBe("object");
|
|
379
|
-
expect(extra).not.toBeNull();
|
|
380
|
-
expect(extra?.associatedTokenId).toBeUndefined();
|
|
381
|
-
});
|
|
382
261
|
});
|
|
383
262
|
|
|
384
263
|
describe("mergeSubAccounts", () => {
|
|
@@ -450,6 +329,7 @@ describe("utils", () => {
|
|
|
450
329
|
|
|
451
330
|
const result = applyPendingExtras([mockedOperation1], [mockedPendingOperation1]);
|
|
452
331
|
|
|
332
|
+
expect(result).toHaveLength(1);
|
|
453
333
|
expect(result[0].extra).toEqual({
|
|
454
334
|
...mockedOperation1.extra,
|
|
455
335
|
...mockedPendingOperation1.extra,
|
|
@@ -464,6 +344,7 @@ describe("utils", () => {
|
|
|
464
344
|
const mockedPendingOperation = getMockedOperation({ hash: "op1", extra: pendingExtra });
|
|
465
345
|
|
|
466
346
|
const result = applyPendingExtras([mockedOperation], [mockedPendingOperation]);
|
|
347
|
+
expect(result).toHaveLength(1);
|
|
467
348
|
expect(result[0].extra).toEqual(mockedOperation.extra);
|
|
468
349
|
});
|
|
469
350
|
});
|
|
@@ -484,112 +365,8 @@ describe("utils", () => {
|
|
|
484
365
|
const patched = patchOperationWithExtra(mockedOperation, extra);
|
|
485
366
|
|
|
486
367
|
expect(patched.extra).toEqual(extra);
|
|
368
|
+
expect(patched.subOperations).toHaveLength(1);
|
|
487
369
|
expect(patched.subOperations?.[0].extra).toEqual(extra);
|
|
488
370
|
});
|
|
489
371
|
});
|
|
490
|
-
|
|
491
|
-
describe("checkAccountTokenAssociationStatus", () => {
|
|
492
|
-
const accountId = "0.0.1234";
|
|
493
|
-
const tokenId = "0.0.5678";
|
|
494
|
-
|
|
495
|
-
beforeEach(() => {
|
|
496
|
-
jest.clearAllMocks();
|
|
497
|
-
// reset LRU cache to make sure all tests receive correct mocks from mockedGetAccount
|
|
498
|
-
checkAccountTokenAssociationStatus.clear(`${accountId}-${tokenId}`);
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
test("returns true if max_automatic_token_associations === -1", async () => {
|
|
502
|
-
mockedGetAccount.mockResolvedValueOnce({
|
|
503
|
-
account: accountId,
|
|
504
|
-
max_automatic_token_associations: -1,
|
|
505
|
-
balance: {
|
|
506
|
-
balance: 0,
|
|
507
|
-
timestamp: "",
|
|
508
|
-
tokens: [],
|
|
509
|
-
},
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
const result = await checkAccountTokenAssociationStatus(accountId, tokenId);
|
|
513
|
-
expect(result).toBe(true);
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
test("returns true if token is already associated", async () => {
|
|
517
|
-
mockedGetAccount.mockResolvedValueOnce({
|
|
518
|
-
account: accountId,
|
|
519
|
-
max_automatic_token_associations: 0,
|
|
520
|
-
balance: {
|
|
521
|
-
balance: 1,
|
|
522
|
-
timestamp: "",
|
|
523
|
-
tokens: [{ token_id: tokenId, balance: 1 }],
|
|
524
|
-
},
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
const result = await checkAccountTokenAssociationStatus(accountId, tokenId);
|
|
528
|
-
expect(result).toBe(true);
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
test("returns false if token is not associated", async () => {
|
|
532
|
-
mockedGetAccount.mockResolvedValueOnce({
|
|
533
|
-
account: accountId,
|
|
534
|
-
max_automatic_token_associations: 0,
|
|
535
|
-
balance: {
|
|
536
|
-
balance: 1,
|
|
537
|
-
timestamp: "",
|
|
538
|
-
tokens: [{ token_id: "0.0.9999", balance: 1 }],
|
|
539
|
-
},
|
|
540
|
-
});
|
|
541
|
-
|
|
542
|
-
const result = await checkAccountTokenAssociationStatus(accountId, tokenId);
|
|
543
|
-
expect(result).toBe(false);
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
test("supports addresses with checksum", async () => {
|
|
547
|
-
const addressWithChecksum = "0.0.9124531-xrxlv";
|
|
548
|
-
|
|
549
|
-
mockedGetAccount.mockResolvedValueOnce({
|
|
550
|
-
account: accountId,
|
|
551
|
-
max_automatic_token_associations: 0,
|
|
552
|
-
balance: {
|
|
553
|
-
balance: 1,
|
|
554
|
-
timestamp: "",
|
|
555
|
-
tokens: [{ token_id: "0.0.9999", balance: 1 }],
|
|
556
|
-
},
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
await checkAccountTokenAssociationStatus(addressWithChecksum, tokenId);
|
|
560
|
-
expect(mockedGetAccount).toHaveBeenCalledWith("0.0.9124531");
|
|
561
|
-
});
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
describe("safeParseAccountId", () => {
|
|
565
|
-
test("returns account id and no checksum for valid address without checksum", () => {
|
|
566
|
-
const [error, result] = safeParseAccountId("0.0.9124531");
|
|
567
|
-
|
|
568
|
-
expect(error).toBeNull();
|
|
569
|
-
expect(result?.accountId).toBe("0.0.9124531");
|
|
570
|
-
expect(result?.checksum).toBeNull();
|
|
571
|
-
});
|
|
572
|
-
|
|
573
|
-
test("returns account id and checksum for valid address with correct checksum", () => {
|
|
574
|
-
const [error, result] = safeParseAccountId("0.0.9124531-xrxlv");
|
|
575
|
-
|
|
576
|
-
expect(error).toBeNull();
|
|
577
|
-
expect(result?.accountId).toBe("0.0.9124531");
|
|
578
|
-
expect(result?.checksum).toBe("xrxlv");
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
test("returns error for valid address with incorrect checksum", () => {
|
|
582
|
-
const [error, accountId] = safeParseAccountId("0.0.9124531-invld");
|
|
583
|
-
|
|
584
|
-
expect(error).toBeInstanceOf(HederaRecipientInvalidChecksum);
|
|
585
|
-
expect(accountId).toBeNull();
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
test("returns error for invalid address format", () => {
|
|
589
|
-
const [error, accountId] = safeParseAccountId("not-a-valid-address");
|
|
590
|
-
|
|
591
|
-
expect(error).toBeInstanceOf(InvalidAddress);
|
|
592
|
-
expect(accountId).toBeNull();
|
|
593
|
-
});
|
|
594
|
-
});
|
|
595
372
|
});
|
package/src/bridge/utils.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
2
|
import murmurhash from "imurmurhash";
|
|
3
|
-
import invariant from "invariant";
|
|
4
|
-
import { AccountId } from "@hashgraph/sdk";
|
|
5
|
-
import { InvalidAddress } from "@ledgerhq/errors";
|
|
6
3
|
import type { Account, Operation, TokenAccount } from "@ledgerhq/types-live";
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
findCryptoCurrencyById,
|
|
10
|
-
findTokenByAddressInCurrency,
|
|
11
|
-
getFiatCurrencyByTicker,
|
|
12
|
-
listTokensForCryptoCurrency,
|
|
13
|
-
} from "@ledgerhq/cryptoassets";
|
|
4
|
+
import { findTokenByAddressInCurrency, listTokensForCryptoCurrency } from "@ledgerhq/cryptoassets";
|
|
14
5
|
import {
|
|
15
6
|
decodeTokenAccountId,
|
|
16
7
|
emptyHistoryCache,
|
|
@@ -19,63 +10,13 @@ import {
|
|
|
19
10
|
isTokenAccount,
|
|
20
11
|
} from "@ledgerhq/coin-framework/account";
|
|
21
12
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
22
|
-
import type { CryptoCurrency,
|
|
13
|
+
import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
23
14
|
import { mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
24
|
-
import {
|
|
15
|
+
import { HEDERA_OPERATION_TYPES } from "../constants";
|
|
25
16
|
import { estimateMaxSpendable } from "./estimateMaxSpendable";
|
|
26
|
-
import
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import type { HederaMirrorToken } from "../api/types";
|
|
30
|
-
import { HederaRecipientInvalidChecksum } from "../errors";
|
|
31
|
-
import { isTokenAssociateTransaction, isValidExtra } from "../logic";
|
|
32
|
-
import { BASE_USD_FEE_BY_OPERATION_TYPE, HEDERA_OPERATION_TYPES } from "../constants";
|
|
33
|
-
|
|
34
|
-
const ESTIMATED_FEE_SAFETY_RATE = 2;
|
|
35
|
-
|
|
36
|
-
// note: this is currently called frequently by getTransactionStatus; LRU cache prevents duplicated requests
|
|
37
|
-
export const getCurrencyToUSDRate = makeLRUCache(
|
|
38
|
-
async (currency: Currency) => {
|
|
39
|
-
try {
|
|
40
|
-
const [rate] = await cvsApi.fetchLatest([
|
|
41
|
-
{
|
|
42
|
-
from: currency,
|
|
43
|
-
to: getFiatCurrencyByTicker("USD"),
|
|
44
|
-
startDate: new Date(),
|
|
45
|
-
},
|
|
46
|
-
]);
|
|
47
|
-
|
|
48
|
-
invariant(rate, "no value returned from cvs api");
|
|
49
|
-
|
|
50
|
-
return new BigNumber(rate);
|
|
51
|
-
} catch {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
currency => currency.ticker,
|
|
56
|
-
seconds(3),
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
export const getEstimatedFees = async (
|
|
60
|
-
account: Account,
|
|
61
|
-
operationType: HEDERA_OPERATION_TYPES,
|
|
62
|
-
): Promise<BigNumber> => {
|
|
63
|
-
try {
|
|
64
|
-
const usdRate = await getCurrencyToUSDRate(account.currency);
|
|
65
|
-
|
|
66
|
-
if (usdRate) {
|
|
67
|
-
return new BigNumber(BASE_USD_FEE_BY_OPERATION_TYPE[operationType])
|
|
68
|
-
.dividedBy(new BigNumber(usdRate))
|
|
69
|
-
.integerValue(BigNumber.ROUND_CEIL)
|
|
70
|
-
.multipliedBy(ESTIMATED_FEE_SAFETY_RATE);
|
|
71
|
-
}
|
|
72
|
-
// eslint-disable-next-line no-empty
|
|
73
|
-
} catch {}
|
|
74
|
-
|
|
75
|
-
// as fees are based on a currency conversion, we stay
|
|
76
|
-
// on the safe side here and double the estimate for "max spendable"
|
|
77
|
-
return new BigNumber("150200").multipliedBy(ESTIMATED_FEE_SAFETY_RATE); // 0.001502 ℏ (as of 2023-03-14)
|
|
78
|
-
};
|
|
17
|
+
import { estimateFees } from "../logic/estimateFees";
|
|
18
|
+
import { isTokenAssociateTransaction, isValidExtra } from "../logic/utils";
|
|
19
|
+
import type { HederaOperationExtra, Transaction, HederaMirrorToken } from "../types";
|
|
79
20
|
|
|
80
21
|
interface CalculateAmountResult {
|
|
81
22
|
amount: BigNumber;
|
|
@@ -91,7 +32,7 @@ const calculateCoinAmount = async ({
|
|
|
91
32
|
transaction: Transaction;
|
|
92
33
|
operationType: HEDERA_OPERATION_TYPES;
|
|
93
34
|
}): Promise<CalculateAmountResult> => {
|
|
94
|
-
const estimatedFees = await
|
|
35
|
+
const estimatedFees = await estimateFees(account.currency, operationType);
|
|
95
36
|
const amount = transaction.useAllAmount
|
|
96
37
|
? await estimateMaxSpendable({ account, transaction })
|
|
97
38
|
: transaction.amount;
|
|
@@ -142,15 +83,6 @@ export const calculateAmount = ({
|
|
|
142
83
|
return calculateCoinAmount({ account, transaction, operationType });
|
|
143
84
|
};
|
|
144
85
|
|
|
145
|
-
// NOTE: convert from the non-url-safe version of base64 to the url-safe version (that the explorer uses)
|
|
146
|
-
export function base64ToUrlSafeBase64(data: string): string {
|
|
147
|
-
// Might be nice to use this alternative if .nvmrc changes to >= Node v14.18.0
|
|
148
|
-
// base64url encoding option isn't supported until then
|
|
149
|
-
// Buffer.from(data, "base64").toString("base64url");
|
|
150
|
-
|
|
151
|
-
return data.replace(/\//g, "_").replace(/\+/g, "-");
|
|
152
|
-
}
|
|
153
|
-
|
|
154
86
|
const simpleSyncHashMemoize: Record<string, string> = {};
|
|
155
87
|
|
|
156
88
|
export const getSyncHash = (
|
|
@@ -265,11 +197,12 @@ export const getSubAccounts = async (
|
|
|
265
197
|
return subAccounts;
|
|
266
198
|
};
|
|
267
199
|
|
|
268
|
-
type CoinOperationForOrphanChildOperation = Operation &
|
|
200
|
+
type CoinOperationForOrphanChildOperation = Operation<HederaOperationExtra> &
|
|
201
|
+
Required<Pick<Operation, "subOperations">>;
|
|
269
202
|
|
|
270
203
|
// create NONE coin operation that will be a parent of an orphan child operation
|
|
271
204
|
const makeCoinOperationForOrphanChildOperation = (
|
|
272
|
-
childOperation: Operation
|
|
205
|
+
childOperation: Operation<HederaOperationExtra>,
|
|
273
206
|
): CoinOperationForOrphanChildOperation => {
|
|
274
207
|
const type = "NONE";
|
|
275
208
|
const { accountId } = decodeTokenAccountId(childOperation.accountId);
|
|
@@ -299,33 +232,15 @@ const makeCoinOperationForOrphanChildOperation = (
|
|
|
299
232
|
// - linking sub operations with coin operations, e.g. token transfer with fee payment
|
|
300
233
|
// - if possible, assigning `extra.associatedTokenId = mirrorToken.tokenId` based on operation's consensus timestamp
|
|
301
234
|
export const prepareOperations = (
|
|
302
|
-
coinOperations: Operation[],
|
|
303
|
-
tokenOperations: Operation[],
|
|
304
|
-
|
|
305
|
-
): Operation[] => {
|
|
235
|
+
coinOperations: Operation<HederaOperationExtra>[],
|
|
236
|
+
tokenOperations: Operation<HederaOperationExtra>[],
|
|
237
|
+
): Operation<HederaOperationExtra>[] => {
|
|
306
238
|
const preparedCoinOperations = coinOperations.map(op => ({ ...op }));
|
|
307
239
|
const preparedTokenOperations = tokenOperations.map(op => ({ ...op }));
|
|
308
240
|
|
|
309
|
-
// loop through coin operations to
|
|
310
|
-
// - enrich ASSOCIATE_TOKEN operations with extra.associatedTokenId
|
|
311
|
-
// - prepare a map of hash => operations
|
|
241
|
+
// loop through coin operations to prepare a map of hash => operations
|
|
312
242
|
const coinOperationsByHash: Record<string, CoinOperationForOrphanChildOperation[]> = {};
|
|
313
243
|
preparedCoinOperations.forEach(op => {
|
|
314
|
-
const extra = isValidExtra(op.extra) ? op.extra : null;
|
|
315
|
-
|
|
316
|
-
if (op.type === "ASSOCIATE_TOKEN" && extra?.consensusTimestamp) {
|
|
317
|
-
const relatedMirrorToken = mirrorTokens.find(t => {
|
|
318
|
-
return t.created_timestamp === extra.consensusTimestamp;
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
if (relatedMirrorToken) {
|
|
322
|
-
op.extra = {
|
|
323
|
-
...extra,
|
|
324
|
-
associatedTokenId: relatedMirrorToken.token_id,
|
|
325
|
-
} satisfies HederaOperationExtra;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
244
|
if (!coinOperationsByHash[op.hash]) {
|
|
330
245
|
coinOperationsByHash[op.hash] = [];
|
|
331
246
|
}
|
|
@@ -456,64 +371,3 @@ export function patchOperationWithExtra(
|
|
|
456
371
|
nftOperations: (operation.nftOperations ?? []).map(op => ({ ...op, extra })),
|
|
457
372
|
};
|
|
458
373
|
}
|
|
459
|
-
|
|
460
|
-
export const checkAccountTokenAssociationStatus = makeLRUCache(
|
|
461
|
-
async (address: string, tokenId: string) => {
|
|
462
|
-
const [parsingError, parsingResult] = safeParseAccountId(address);
|
|
463
|
-
|
|
464
|
-
if (parsingError) {
|
|
465
|
-
throw parsingError;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
const addressWithoutChecksum = parsingResult.accountId;
|
|
469
|
-
const mirrorAccount = await getAccount(addressWithoutChecksum);
|
|
470
|
-
|
|
471
|
-
// auto association is enabled
|
|
472
|
-
if (mirrorAccount.max_automatic_token_associations === -1) {
|
|
473
|
-
return true;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const isTokenAssociated = mirrorAccount.balance.tokens.some(token => {
|
|
477
|
-
return token.token_id === tokenId;
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
return isTokenAssociated;
|
|
481
|
-
},
|
|
482
|
-
(accountId, tokenId) => `${accountId}-${tokenId}`,
|
|
483
|
-
seconds(30),
|
|
484
|
-
);
|
|
485
|
-
|
|
486
|
-
export const safeParseAccountId = (
|
|
487
|
-
address: string,
|
|
488
|
-
): [Error, null] | [null, { accountId: string; checksum: string | null }] => {
|
|
489
|
-
const currency = findCryptoCurrencyById("hedera");
|
|
490
|
-
const currencyName = currency?.name ?? "Hedera";
|
|
491
|
-
|
|
492
|
-
try {
|
|
493
|
-
const accountId = AccountId.fromString(address);
|
|
494
|
-
|
|
495
|
-
// verify checksum if present
|
|
496
|
-
// FIXME: migrate to EntityIdHelper methods once SDK is upgraded:
|
|
497
|
-
// https://github.com/hiero-ledger/hiero-sdk-js/blob/main/src/EntityIdHelper.js#L197
|
|
498
|
-
// https://github.com/hiero-ledger/hiero-sdk-js/blob/main/src/EntityIdHelper.js#L446
|
|
499
|
-
const checksum: string | null = address.split("-")[1] ?? null;
|
|
500
|
-
if (checksum) {
|
|
501
|
-
const client = getHederaClient();
|
|
502
|
-
const recipientWithChecksum = accountId.toStringWithChecksum(client);
|
|
503
|
-
const expectedChecksum = recipientWithChecksum.split("-")[1];
|
|
504
|
-
|
|
505
|
-
if (checksum !== expectedChecksum) {
|
|
506
|
-
return [new HederaRecipientInvalidChecksum(), null];
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
const result = {
|
|
511
|
-
accountId: accountId.toString(),
|
|
512
|
-
checksum,
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
return [null, result];
|
|
516
|
-
} catch (err) {
|
|
517
|
-
return [new InvalidAddress("", { currencyName }), null];
|
|
518
|
-
}
|
|
519
|
-
};
|
package/src/config.ts
ADDED
package/src/constants.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Internal types
|
|
3
|
-
* These can be
|
|
2
|
+
* Internal types to distinguish custom Hedera transaction behaviors.
|
|
3
|
+
* These can be used in transaction.mode and used to route specific preparation logic.
|
|
4
4
|
*/
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} as const satisfies Record<string, Record<string, unknown> & { name: string }>;
|
|
5
|
+
export enum HEDERA_TRANSACTION_MODES {
|
|
6
|
+
Send = "send",
|
|
7
|
+
TokenAssociate = "token-associate",
|
|
8
|
+
}
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Enum representing the supported Hedera operation types for fee estimation
|
|
@@ -17,7 +16,14 @@ export enum HEDERA_OPERATION_TYPES {
|
|
|
17
16
|
TokenAssociate = "TokenAssociate",
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
const TINYBAR_SCALE = 8;
|
|
19
|
+
export const TINYBAR_SCALE = 8;
|
|
20
|
+
|
|
21
|
+
export const ESTIMATED_FEE_SAFETY_RATE = 2;
|
|
22
|
+
|
|
23
|
+
// old value moved from https://github.com/LedgerHQ/ledger-live/blob/8447b68b7c6f1e7ccd4aa9db4da0e6c8de36a88e/libs/coin-modules/coin-hedera/src/bridge/utils.ts#L77
|
|
24
|
+
export const DEFAULT_TINYBAR_FEE = 150200;
|
|
25
|
+
|
|
26
|
+
export const SYNTHETIC_BLOCK_WINDOW_SECONDS = 10;
|
|
21
27
|
|
|
22
28
|
/**
|
|
23
29
|
* https://docs.hedera.com/hedera/networks/mainnet/fees
|
|
@@ -25,7 +31,7 @@ const TINYBAR_SCALE = 8;
|
|
|
25
31
|
* These are Hedera's estimated fee costs in USD, scaled to tinybars (1 HBAR = 10^8 tinybars),
|
|
26
32
|
* so they can be converted into actual HBAR amounts based on current USD/crypto rates.
|
|
27
33
|
*
|
|
28
|
-
* Used in fee estimation logic (
|
|
34
|
+
* Used in fee estimation logic (estimateFees function) to determine whether an account
|
|
29
35
|
* has sufficient balance to cover the cost of a transaction (e.g. token association).
|
|
30
36
|
*/
|
|
31
37
|
export const BASE_USD_FEE_BY_OPERATION_TYPE = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AccountLike, Account } from "@ledgerhq/types-live";
|
|
2
|
-
import type { Transaction, TransactionStatus } from "./types";
|
|
3
2
|
import type { CommonDeviceTransactionField as DeviceTransactionField } from "@ledgerhq/coin-framework/transaction/common";
|
|
4
|
-
import { isTokenAssociateTransaction } from "./logic";
|
|
3
|
+
import { isTokenAssociateTransaction } from "./logic/utils";
|
|
4
|
+
import type { Transaction, TransactionStatus } from "./types";
|
|
5
5
|
|
|
6
6
|
async function getDeviceTransactionConfig({
|
|
7
7
|
transaction,
|