@ledgerhq/coin-hedera 1.12.1-nightly.1 → 1.13.0-nightly.3
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 +29 -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 +2 -2
- package/lib/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/deviceTransactionConfig.js +4 -4
- 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 +2 -2
- package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
- package/lib-es/deviceTransactionConfig.js +2 -2
- 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 +19 -248
- package/src/bridge/utils.ts +14 -160
- package/src/config.ts +7 -0
- package/src/constants.ts +15 -9
- package/src/deviceTransactionConfig.ts +4 -4
- 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
package/src/api/mirror.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import network from "@ledgerhq/live-network/network";
|
|
2
|
-
import { getEnv } from "@ledgerhq/live-env";
|
|
3
|
-
import type { HederaMirrorAccount, HederaMirrorToken, HederaMirrorTransaction } from "./types";
|
|
4
|
-
import { HederaAddAccountError } from "../errors";
|
|
5
|
-
import { LedgerAPI4xx } from "@ledgerhq/errors";
|
|
6
|
-
|
|
7
|
-
const getMirrorApiUrl = (): string => getEnv("API_HEDERA_MIRROR");
|
|
8
|
-
|
|
9
|
-
const fetch = (path: string) => {
|
|
10
|
-
return network({
|
|
11
|
-
method: "GET",
|
|
12
|
-
url: `${getMirrorApiUrl()}${path}`,
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export async function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorAccount[]> {
|
|
17
|
-
let r;
|
|
18
|
-
try {
|
|
19
|
-
r = await fetch(`/api/v1/accounts?account.publicKey=${publicKey}&balance=true&limit=100`);
|
|
20
|
-
} catch (e: any) {
|
|
21
|
-
if (e.name === "LedgerAPI4xx") return [];
|
|
22
|
-
throw e;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const accounts = r.data.accounts as HederaMirrorAccount[];
|
|
26
|
-
|
|
27
|
-
return accounts;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function getAccount(address: string): Promise<HederaMirrorAccount> {
|
|
31
|
-
try {
|
|
32
|
-
const res = await fetch(`/api/v1/accounts/${address}`);
|
|
33
|
-
const account = res.data as HederaMirrorAccount;
|
|
34
|
-
|
|
35
|
-
return account;
|
|
36
|
-
} catch (error) {
|
|
37
|
-
if (error instanceof LedgerAPI4xx && "status" in error && error.status === 404) {
|
|
38
|
-
throw new HederaAddAccountError();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
throw error;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function getAccountTransactions(
|
|
46
|
-
address: string,
|
|
47
|
-
since: string | null,
|
|
48
|
-
): Promise<HederaMirrorTransaction[]> {
|
|
49
|
-
const transactions: HederaMirrorTransaction[] = [];
|
|
50
|
-
const params = new URLSearchParams({
|
|
51
|
-
"account.id": address,
|
|
52
|
-
order: "desc",
|
|
53
|
-
limit: "100",
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
if (since) {
|
|
57
|
-
params.append("timestamp", `gt:${since}`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
let nextUrl = `/api/v1/transactions?${params.toString()}`;
|
|
61
|
-
|
|
62
|
-
// WARNING: don't break the loop when `transactions` array is empty but `links.next` is present
|
|
63
|
-
// the mirror node API enforces a 60-day max time range per query, even if `timestamp` param is set
|
|
64
|
-
// see: https://hedera.com/blog/changes-to-the-hedera-operated-mirror-node
|
|
65
|
-
while (nextUrl) {
|
|
66
|
-
const res = await fetch(nextUrl);
|
|
67
|
-
const newTransactions = res.data.transactions as HederaMirrorTransaction[];
|
|
68
|
-
transactions.push(...newTransactions);
|
|
69
|
-
nextUrl = res.data.links.next;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return transactions;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export async function getAccountTokens(address: string): Promise<HederaMirrorToken[]> {
|
|
76
|
-
const tokens: HederaMirrorToken[] = [];
|
|
77
|
-
const params = new URLSearchParams({
|
|
78
|
-
limit: "100",
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
let nextUrl = `/api/v1/accounts/${address}/tokens?${params.toString()}`;
|
|
82
|
-
|
|
83
|
-
while (nextUrl) {
|
|
84
|
-
const res = await fetch(nextUrl);
|
|
85
|
-
const newTokens = res.data.tokens as HederaMirrorToken[];
|
|
86
|
-
tokens.push(...newTokens);
|
|
87
|
-
nextUrl = res.data.links.next;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return tokens;
|
|
91
|
-
}
|
package/src/api/network.test.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import BigNumber from "bignumber.js";
|
|
2
|
-
import { TransferTransaction } from "@hashgraph/sdk";
|
|
3
|
-
import type { Account } from "@ledgerhq/types-live";
|
|
4
|
-
import { buildUnsignedTransaction } from "./network";
|
|
5
|
-
import { Transaction } from "../types";
|
|
6
|
-
import invariant from "invariant";
|
|
7
|
-
|
|
8
|
-
describe("buildUnsignedTransaction", () => {
|
|
9
|
-
const mockAccount = {
|
|
10
|
-
freshAddress: "0.0.123",
|
|
11
|
-
id: "hedera:0:0.0.123",
|
|
12
|
-
balance: new BigNumber(1000),
|
|
13
|
-
} as Account;
|
|
14
|
-
|
|
15
|
-
test("builds basic transaction without maxFee", async () => {
|
|
16
|
-
const transaction: Transaction = {
|
|
17
|
-
family: "hedera",
|
|
18
|
-
amount: new BigNumber(100),
|
|
19
|
-
recipient: "0.0.456",
|
|
20
|
-
memo: "test memo",
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const result = await buildUnsignedTransaction({ account: mockAccount, transaction });
|
|
24
|
-
|
|
25
|
-
expect(result).toBeInstanceOf(TransferTransaction);
|
|
26
|
-
invariant(result instanceof TransferTransaction, "hedera: TransferTransaction type guard");
|
|
27
|
-
expect(result.transactionMemo).toBe("test memo");
|
|
28
|
-
expect(result.isFrozen()).toBe(true);
|
|
29
|
-
expect(result.hbarTransfers.size).toBe(2);
|
|
30
|
-
|
|
31
|
-
const senderTransfer = result.hbarTransfers.get("0.0.123");
|
|
32
|
-
const recipientTransfer = result.hbarTransfers.get("0.0.456");
|
|
33
|
-
|
|
34
|
-
expect(senderTransfer?.toTinybars().toNumber()).toBe(-100);
|
|
35
|
-
expect(recipientTransfer?.toTinybars().toNumber()).toBe(100);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("sets max transaction fee when provided", async () => {
|
|
39
|
-
const transaction: Transaction = {
|
|
40
|
-
family: "hedera",
|
|
41
|
-
amount: new BigNumber(100),
|
|
42
|
-
recipient: "0.0.456",
|
|
43
|
-
maxFee: new BigNumber(50),
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const result = await buildUnsignedTransaction({ account: mockAccount, transaction });
|
|
47
|
-
expect(result.maxTransactionFee?.toTinybars().toNumber()).toBe(50);
|
|
48
|
-
});
|
|
49
|
-
});
|
package/src/api/network.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import invariant from "invariant";
|
|
2
|
-
import type { Transaction as HederaTransaction, TransactionResponse } from "@hashgraph/sdk";
|
|
3
|
-
import {
|
|
4
|
-
Client,
|
|
5
|
-
TransferTransaction,
|
|
6
|
-
Hbar,
|
|
7
|
-
AccountId,
|
|
8
|
-
TransactionId,
|
|
9
|
-
TokenAssociateTransaction,
|
|
10
|
-
} from "@hashgraph/sdk";
|
|
11
|
-
import type { Account, TokenAccount } from "@ledgerhq/types-live";
|
|
12
|
-
import { findSubAccountById, isTokenAccount } from "@ledgerhq/coin-framework/account/helpers";
|
|
13
|
-
import { Transaction } from "../types";
|
|
14
|
-
import { isTokenAssociateTransaction } from "../logic";
|
|
15
|
-
|
|
16
|
-
export function broadcastTransaction(transaction: HederaTransaction): Promise<TransactionResponse> {
|
|
17
|
-
return transaction.execute(getHederaClient());
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// https://github.com/LedgerHQ/ledger-live/pull/72/commits/1e942687d4301660e43e0c4b5419fcfa2733b290
|
|
21
|
-
const nodeAccountIds: AccountId[] = [new AccountId(3)];
|
|
22
|
-
|
|
23
|
-
async function buildUnsignedCoinTransaction({
|
|
24
|
-
account,
|
|
25
|
-
transaction,
|
|
26
|
-
}: {
|
|
27
|
-
account: Account;
|
|
28
|
-
transaction: Transaction;
|
|
29
|
-
}): Promise<TransferTransaction> {
|
|
30
|
-
const accountId = account.freshAddress;
|
|
31
|
-
const hbarAmount = Hbar.fromTinybars(transaction.amount);
|
|
32
|
-
|
|
33
|
-
const tx = new TransferTransaction()
|
|
34
|
-
.setNodeAccountIds(nodeAccountIds)
|
|
35
|
-
.setTransactionId(TransactionId.generate(accountId))
|
|
36
|
-
.setTransactionMemo(transaction.memo ?? "")
|
|
37
|
-
.addHbarTransfer(accountId, hbarAmount.negated())
|
|
38
|
-
.addHbarTransfer(transaction.recipient, hbarAmount);
|
|
39
|
-
|
|
40
|
-
if (transaction.maxFee) {
|
|
41
|
-
tx.setMaxTransactionFee(Hbar.fromTinybars(transaction.maxFee.toNumber()));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return tx.freeze();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async function buildUnsignedTokenTransaction({
|
|
48
|
-
account,
|
|
49
|
-
tokenAccount,
|
|
50
|
-
transaction,
|
|
51
|
-
}: {
|
|
52
|
-
account: Account;
|
|
53
|
-
tokenAccount: TokenAccount;
|
|
54
|
-
transaction: Transaction;
|
|
55
|
-
}): Promise<TransferTransaction> {
|
|
56
|
-
const accountId = account.freshAddress;
|
|
57
|
-
const tokenId = tokenAccount.token.contractAddress;
|
|
58
|
-
|
|
59
|
-
const tx = new TransferTransaction()
|
|
60
|
-
.setNodeAccountIds(nodeAccountIds)
|
|
61
|
-
.setTransactionId(TransactionId.generate(accountId))
|
|
62
|
-
.setTransactionMemo(transaction.memo ?? "")
|
|
63
|
-
.addTokenTransfer(tokenId, accountId, transaction.amount.negated().toNumber())
|
|
64
|
-
.addTokenTransfer(tokenId, transaction.recipient, transaction.amount.toNumber());
|
|
65
|
-
|
|
66
|
-
if (transaction.maxFee) {
|
|
67
|
-
tx.setMaxTransactionFee(Hbar.fromTinybars(transaction.maxFee.toNumber()));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return tx.freeze();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async function buildTokenAssociateTransaction({
|
|
74
|
-
account,
|
|
75
|
-
transaction,
|
|
76
|
-
}: {
|
|
77
|
-
account: Account;
|
|
78
|
-
transaction: Transaction;
|
|
79
|
-
}): Promise<TokenAssociateTransaction> {
|
|
80
|
-
invariant(isTokenAssociateTransaction(transaction), "invalid transaction properties");
|
|
81
|
-
|
|
82
|
-
const accountId = account.freshAddress;
|
|
83
|
-
|
|
84
|
-
const tx = new TokenAssociateTransaction()
|
|
85
|
-
.setNodeAccountIds(nodeAccountIds)
|
|
86
|
-
.setTransactionId(TransactionId.generate(accountId))
|
|
87
|
-
.setTransactionMemo(transaction.memo ?? "")
|
|
88
|
-
.setAccountId(accountId)
|
|
89
|
-
.setTokenIds([transaction.properties.token.contractAddress]);
|
|
90
|
-
|
|
91
|
-
if (transaction.maxFee) {
|
|
92
|
-
tx.setMaxTransactionFee(Hbar.fromTinybars(transaction.maxFee.toNumber()));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return tx.freeze();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export async function buildUnsignedTransaction({
|
|
99
|
-
account,
|
|
100
|
-
transaction,
|
|
101
|
-
}: {
|
|
102
|
-
account: Account;
|
|
103
|
-
transaction: Transaction;
|
|
104
|
-
}): Promise<TransferTransaction | TokenAssociateTransaction> {
|
|
105
|
-
const subAccount = findSubAccountById(account, transaction?.subAccountId || "");
|
|
106
|
-
const isTokenTransaction = isTokenAccount(subAccount);
|
|
107
|
-
|
|
108
|
-
if (isTokenAssociateTransaction(transaction)) {
|
|
109
|
-
return buildTokenAssociateTransaction({ account, transaction });
|
|
110
|
-
} else if (isTokenTransaction) {
|
|
111
|
-
return buildUnsignedTokenTransaction({ account, tokenAccount: subAccount, transaction });
|
|
112
|
-
} else {
|
|
113
|
-
return buildUnsignedCoinTransaction({ account, transaction });
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
let _hederaClient: Client | null = null;
|
|
118
|
-
|
|
119
|
-
export function getHederaClient(): Client {
|
|
120
|
-
_hederaClient ??= Client.forMainnet().setMaxNodesPerTransaction(1);
|
|
121
|
-
|
|
122
|
-
//_hederaClient.setNetwork({ mainnet: "https://hedera.coin.ledger.com" });
|
|
123
|
-
|
|
124
|
-
return _hederaClient;
|
|
125
|
-
}
|
package/src/api/utils.ts
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import BigNumber from "bignumber.js";
|
|
2
|
-
import { AccountId } from "@hashgraph/sdk";
|
|
3
|
-
import type { Operation, OperationType } from "@ledgerhq/types-live";
|
|
4
|
-
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
5
|
-
import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account";
|
|
6
|
-
import { findTokenByAddressInCurrency } from "@ledgerhq/cryptoassets";
|
|
7
|
-
import type { HederaMirrorTokenTransfer, HederaMirrorCoinTransfer } from "./types";
|
|
8
|
-
import { getAccountTransactions } from "./mirror";
|
|
9
|
-
import { base64ToUrlSafeBase64 } from "../bridge/utils";
|
|
10
|
-
|
|
11
|
-
function isValidRecipient(accountId: AccountId, recipients: string[]): boolean {
|
|
12
|
-
if (accountId.shard.eq(0) && accountId.realm.eq(0)) {
|
|
13
|
-
// account is a node, only add to list if we have none
|
|
14
|
-
if (accountId.num.lt(100)) {
|
|
15
|
-
return recipients.length === 0;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// account is a system account that is not a node, do NOT add
|
|
19
|
-
if (accountId.num.lt(1000)) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function parseTransfers(
|
|
28
|
-
mirrorTransfers: (HederaMirrorCoinTransfer | HederaMirrorTokenTransfer)[],
|
|
29
|
-
address: string,
|
|
30
|
-
): Pick<Operation, "type" | "value" | "senders" | "recipients"> {
|
|
31
|
-
let value = new BigNumber(0);
|
|
32
|
-
let type: OperationType = "NONE";
|
|
33
|
-
|
|
34
|
-
const senders: string[] = [];
|
|
35
|
-
const recipients: string[] = [];
|
|
36
|
-
|
|
37
|
-
for (const transfer of mirrorTransfers) {
|
|
38
|
-
const amount = new BigNumber(transfer.amount);
|
|
39
|
-
const accountId = AccountId.fromString(transfer.account);
|
|
40
|
-
|
|
41
|
-
if (transfer.account === address) {
|
|
42
|
-
value = amount.abs();
|
|
43
|
-
type = amount.isNegative() ? "OUT" : "IN";
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (amount.isNegative()) {
|
|
47
|
-
senders.push(transfer.account);
|
|
48
|
-
} else if (isValidRecipient(accountId, recipients)) {
|
|
49
|
-
recipients.push(transfer.account);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// NOTE: earlier addresses are the "fee" addresses
|
|
54
|
-
senders.reverse();
|
|
55
|
-
recipients.reverse();
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
type,
|
|
59
|
-
value,
|
|
60
|
-
senders,
|
|
61
|
-
recipients,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export async function getOperationsForAccount(
|
|
66
|
-
ledgerAccountId: string,
|
|
67
|
-
address: string,
|
|
68
|
-
latestOperationTimestamp: string | null,
|
|
69
|
-
): Promise<{
|
|
70
|
-
coinOperations: Operation[];
|
|
71
|
-
tokenOperations: Operation[];
|
|
72
|
-
}> {
|
|
73
|
-
const mirrorTransactions = await getAccountTransactions(address, latestOperationTimestamp);
|
|
74
|
-
const coinOperations: Operation[] = [];
|
|
75
|
-
const tokenOperations: Operation[] = [];
|
|
76
|
-
|
|
77
|
-
for (const rawTx of mirrorTransactions) {
|
|
78
|
-
const timestamp = new Date(parseInt(rawTx.consensus_timestamp.split(".")[0], 10) * 1000);
|
|
79
|
-
const hash = base64ToUrlSafeBase64(rawTx.transaction_hash);
|
|
80
|
-
const fee = new BigNumber(rawTx.charged_tx_fee);
|
|
81
|
-
const tokenTransfers = rawTx.token_transfers ?? [];
|
|
82
|
-
const transfers = rawTx.transfers ?? [];
|
|
83
|
-
const hasFailed = rawTx.result !== "SUCCESS";
|
|
84
|
-
|
|
85
|
-
if (tokenTransfers.length > 0) {
|
|
86
|
-
const tokenId = rawTx.token_transfers[0].token_id;
|
|
87
|
-
const token = findTokenByAddressInCurrency(tokenId, "hedera");
|
|
88
|
-
if (!token) continue;
|
|
89
|
-
|
|
90
|
-
const encodedTokenId = encodeTokenAccountId(ledgerAccountId, token);
|
|
91
|
-
const { type, value, senders, recipients } = parseTransfers(rawTx.token_transfers, address);
|
|
92
|
-
|
|
93
|
-
// add main FEES coin operation for send token transfer
|
|
94
|
-
if (type === "OUT") {
|
|
95
|
-
coinOperations.push({
|
|
96
|
-
id: encodeOperationId(ledgerAccountId, hash, "FEES"),
|
|
97
|
-
accountId: ledgerAccountId,
|
|
98
|
-
type: "FEES",
|
|
99
|
-
value: fee,
|
|
100
|
-
recipients,
|
|
101
|
-
senders,
|
|
102
|
-
hash,
|
|
103
|
-
fee,
|
|
104
|
-
date: timestamp,
|
|
105
|
-
blockHeight: 5,
|
|
106
|
-
blockHash: null,
|
|
107
|
-
hasFailed,
|
|
108
|
-
extra: { consensusTimestamp: rawTx.consensus_timestamp },
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
tokenOperations.push({
|
|
113
|
-
id: encodeOperationId(encodedTokenId, hash, type),
|
|
114
|
-
accountId: encodedTokenId,
|
|
115
|
-
type,
|
|
116
|
-
value,
|
|
117
|
-
recipients,
|
|
118
|
-
senders,
|
|
119
|
-
hash,
|
|
120
|
-
fee,
|
|
121
|
-
date: timestamp,
|
|
122
|
-
blockHeight: 5,
|
|
123
|
-
blockHash: null,
|
|
124
|
-
hasFailed,
|
|
125
|
-
extra: { consensusTimestamp: rawTx.consensus_timestamp },
|
|
126
|
-
});
|
|
127
|
-
} else if (transfers.length > 0) {
|
|
128
|
-
const { type, value, senders, recipients } = parseTransfers(rawTx.transfers, address);
|
|
129
|
-
const operationType = rawTx.name === "TOKENASSOCIATE" ? "ASSOCIATE_TOKEN" : type;
|
|
130
|
-
|
|
131
|
-
coinOperations.push({
|
|
132
|
-
id: encodeOperationId(ledgerAccountId, hash, operationType),
|
|
133
|
-
accountId: ledgerAccountId,
|
|
134
|
-
type: operationType,
|
|
135
|
-
value,
|
|
136
|
-
recipients,
|
|
137
|
-
senders,
|
|
138
|
-
hash,
|
|
139
|
-
fee,
|
|
140
|
-
date: timestamp,
|
|
141
|
-
blockHeight: 5,
|
|
142
|
-
blockHash: null,
|
|
143
|
-
hasFailed,
|
|
144
|
-
extra: { consensusTimestamp: rawTx.consensus_timestamp },
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return { coinOperations, tokenOperations };
|
|
150
|
-
}
|
package/src/logic.test.ts
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets";
|
|
2
|
-
import {
|
|
3
|
-
getTransactionExplorer,
|
|
4
|
-
isAutoTokenAssociationEnabled,
|
|
5
|
-
isTokenAssociateTransaction,
|
|
6
|
-
isTokenAssociationRequired,
|
|
7
|
-
isValidExtra,
|
|
8
|
-
sendRecipientCanNext,
|
|
9
|
-
} from "./logic";
|
|
10
|
-
import { getMockedAccount, getMockedTokenAccount } from "./test/fixtures/account.fixture";
|
|
11
|
-
import { getMockedOperation } from "./test/fixtures/operation.fixture";
|
|
12
|
-
import { getMockedTokenCurrency } from "./test/fixtures/currency.fixture";
|
|
13
|
-
import { HEDERA_TRANSACTION_KINDS } from "./constants";
|
|
14
|
-
|
|
15
|
-
describe("logic", () => {
|
|
16
|
-
describe("getTransactionExplorer", () => {
|
|
17
|
-
test("Tx explorer URL is converted from hash to consensus timestamp", async () => {
|
|
18
|
-
const explorerView = getCryptoCurrencyById("hedera").explorerViews[0];
|
|
19
|
-
expect(explorerView).toEqual({
|
|
20
|
-
tx: expect.any(String),
|
|
21
|
-
address: expect.any(String),
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const mockedOperation = getMockedOperation({
|
|
25
|
-
extra: { consensusTimestamp: "1.2.3.4" },
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const newUrl = getTransactionExplorer(explorerView, mockedOperation);
|
|
29
|
-
expect(newUrl).toBe("https://hashscan.io/mainnet/transaction/1.2.3.4");
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test("Tx explorer URL is based on transaction id if consensus timestamp is not available", async () => {
|
|
33
|
-
const explorerView = getCryptoCurrencyById("hedera").explorerViews[0];
|
|
34
|
-
expect(explorerView).toEqual({
|
|
35
|
-
tx: expect.any(String),
|
|
36
|
-
address: expect.any(String),
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
const mockedOperation = getMockedOperation({
|
|
40
|
-
extra: { transactionId: "0.0.1234567-123-123" },
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const newUrl = getTransactionExplorer(explorerView, mockedOperation);
|
|
44
|
-
expect(newUrl).toBe("https://hashscan.io/mainnet/transaction/0.0.1234567-123-123");
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
describe("isTokenAssociateTransaction", () => {
|
|
49
|
-
test("returns correct value based on tx.properties", () => {
|
|
50
|
-
expect(
|
|
51
|
-
isTokenAssociateTransaction({
|
|
52
|
-
properties: { name: HEDERA_TRANSACTION_KINDS.TokenAssociate.name },
|
|
53
|
-
} as any),
|
|
54
|
-
).toBe(true);
|
|
55
|
-
|
|
56
|
-
expect(
|
|
57
|
-
isTokenAssociateTransaction({
|
|
58
|
-
properties: { name: "transfer" },
|
|
59
|
-
} as any),
|
|
60
|
-
).toBe(false);
|
|
61
|
-
|
|
62
|
-
expect(isTokenAssociateTransaction({} as any)).toBe(false);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
describe("isAutoTokenAssociationEnabled", () => {
|
|
67
|
-
test("returns value based on isAutoTokenAssociationEnabled flag", () => {
|
|
68
|
-
expect(
|
|
69
|
-
isAutoTokenAssociationEnabled({
|
|
70
|
-
hederaResources: { isAutoTokenAssociationEnabled: true },
|
|
71
|
-
} as any),
|
|
72
|
-
).toBe(true);
|
|
73
|
-
|
|
74
|
-
expect(
|
|
75
|
-
isAutoTokenAssociationEnabled({
|
|
76
|
-
hederaResources: { isAutoTokenAssociationEnabled: false },
|
|
77
|
-
} as any),
|
|
78
|
-
).toBe(false);
|
|
79
|
-
|
|
80
|
-
expect(isAutoTokenAssociationEnabled({} as any)).toBe(false);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
describe("isTokenAssociationRequired", () => {
|
|
85
|
-
test("should return false if token is already associated (token account exists)", () => {
|
|
86
|
-
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
87
|
-
const mockedTokenAccount = getMockedTokenAccount(mockedTokenCurrency);
|
|
88
|
-
const mockedAccount = getMockedAccount({ subAccounts: [mockedTokenAccount] });
|
|
89
|
-
|
|
90
|
-
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(false);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test("should return false if auto token associations are enabled", () => {
|
|
94
|
-
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
95
|
-
const mockedAccount = getMockedAccount({
|
|
96
|
-
subAccounts: [],
|
|
97
|
-
hederaResources: {
|
|
98
|
-
maxAutomaticTokenAssociations: -1,
|
|
99
|
-
isAutoTokenAssociationEnabled: true,
|
|
100
|
-
},
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(false);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test("should return true if token is not associated and auto associations are disabled", () => {
|
|
107
|
-
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
108
|
-
const mockedAccount = getMockedAccount({ subAccounts: [] });
|
|
109
|
-
|
|
110
|
-
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(true);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test("should return false if token is undefined", () => {
|
|
114
|
-
const mockedAccount = getMockedAccount({ subAccounts: [] });
|
|
115
|
-
|
|
116
|
-
expect(isTokenAssociationRequired(mockedAccount, undefined)).toBe(false);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test("should return false for legacy accounts without subAccounts or hederaResources", () => {
|
|
120
|
-
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
121
|
-
const mockedAccount = getMockedAccount();
|
|
122
|
-
|
|
123
|
-
delete mockedAccount.subAccounts;
|
|
124
|
-
delete mockedAccount.hederaResources;
|
|
125
|
-
|
|
126
|
-
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(true);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe("isValidExtra", () => {
|
|
131
|
-
test("returns true for object and false for invalid types", () => {
|
|
132
|
-
expect(isValidExtra({ some: "value" })).toBe(true);
|
|
133
|
-
expect(isValidExtra(null)).toBe(false);
|
|
134
|
-
expect(isValidExtra(undefined)).toBe(false);
|
|
135
|
-
expect(isValidExtra("string")).toBe(false);
|
|
136
|
-
expect(isValidExtra(123)).toBe(false);
|
|
137
|
-
expect(isValidExtra([])).toBe(false);
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe("sendRecipientCanNext", () => {
|
|
142
|
-
test("handles association warnings", () => {
|
|
143
|
-
expect(sendRecipientCanNext({ warnings: {} } as any)).toBe(true);
|
|
144
|
-
expect(sendRecipientCanNext({ warnings: { missingAssociation: new Error() } } as any)).toBe(
|
|
145
|
-
false,
|
|
146
|
-
);
|
|
147
|
-
expect(
|
|
148
|
-
sendRecipientCanNext({ warnings: { unverifiedAssociation: new Error() } } as any),
|
|
149
|
-
).toBe(false);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
package/src/logic.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import type { ExplorerView, TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
2
|
-
import type { AccountLike, Operation } from "@ledgerhq/types-live";
|
|
3
|
-
import { HEDERA_TRANSACTION_KINDS } from "./constants";
|
|
4
|
-
import type {
|
|
5
|
-
HederaAccount,
|
|
6
|
-
HederaOperationExtra,
|
|
7
|
-
TokenAssociateProperties,
|
|
8
|
-
Transaction,
|
|
9
|
-
TransactionStatus,
|
|
10
|
-
} from "./types";
|
|
11
|
-
|
|
12
|
-
const getTransactionExplorer = (
|
|
13
|
-
explorerView: ExplorerView | null | undefined,
|
|
14
|
-
operation: Operation,
|
|
15
|
-
): string | undefined => {
|
|
16
|
-
const extra = isValidExtra(operation.extra) ? operation.extra : null;
|
|
17
|
-
|
|
18
|
-
return explorerView?.tx?.replace(
|
|
19
|
-
"$hash",
|
|
20
|
-
extra?.consensusTimestamp ?? extra?.transactionId ?? "0",
|
|
21
|
-
);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const isTokenAssociateTransaction = (
|
|
25
|
-
tx: Transaction,
|
|
26
|
-
): tx is Extract<Required<Transaction>, { properties: TokenAssociateProperties }> => {
|
|
27
|
-
return tx.properties?.name === HEDERA_TRANSACTION_KINDS.TokenAssociate.name;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const isAutoTokenAssociationEnabled = (account: AccountLike) => {
|
|
31
|
-
const hederaAccount = "hederaResources" in account ? (account as HederaAccount) : null;
|
|
32
|
-
|
|
33
|
-
return hederaAccount?.hederaResources?.isAutoTokenAssociationEnabled ?? false;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const isTokenAssociationRequired = (
|
|
37
|
-
account: AccountLike,
|
|
38
|
-
token: TokenCurrency | null | undefined,
|
|
39
|
-
) => {
|
|
40
|
-
const subAccounts = !!account && "subAccounts" in account ? account.subAccounts ?? [] : [];
|
|
41
|
-
const isTokenAssociated = subAccounts.some(item => item.token.id === token?.id);
|
|
42
|
-
|
|
43
|
-
return !!token && !isTokenAssociated && !isAutoTokenAssociationEnabled(account);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const isValidExtra = (extra: unknown): extra is HederaOperationExtra => {
|
|
47
|
-
return !!extra && typeof extra === "object" && !Array.isArray(extra);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// disables the "Continue" button in the Send modal's Recipient step during token transfers if:
|
|
51
|
-
// - the recipient is not associated with the token
|
|
52
|
-
// - the association status can't be verified
|
|
53
|
-
const sendRecipientCanNext = (status: TransactionStatus) => {
|
|
54
|
-
const { missingAssociation, unverifiedAssociation } = status.warnings;
|
|
55
|
-
|
|
56
|
-
return !missingAssociation && !unverifiedAssociation;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export {
|
|
60
|
-
sendRecipientCanNext,
|
|
61
|
-
getTransactionExplorer,
|
|
62
|
-
isValidExtra,
|
|
63
|
-
isTokenAssociateTransaction,
|
|
64
|
-
isTokenAssociationRequired,
|
|
65
|
-
isAutoTokenAssociationEnabled,
|
|
66
|
-
};
|