@ledgerhq/coin-tron 0.0.1
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/.eslintrc.js +20 -0
- package/.turbo/turbo-build.log +4 -0
- package/.unimportedrc.json +25 -0
- package/LICENSE.txt +21 -0
- package/jest.config.js +8 -0
- package/jest.integ.config.js +7 -0
- package/lib/bridge/broadcast.d.ts +7 -0
- package/lib/bridge/broadcast.d.ts.map +1 -0
- package/lib/bridge/broadcast.js +26 -0
- package/lib/bridge/broadcast.js.map +1 -0
- package/lib/bridge/buildOptimisticOperation.d.ts +5 -0
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -0
- package/lib/bridge/buildOptimisticOperation.js +101 -0
- package/lib/bridge/buildOptimisticOperation.js.map +1 -0
- package/lib/bridge/createTransaction.d.ts +4 -0
- package/lib/bridge/createTransaction.d.ts.map +1 -0
- package/lib/bridge/createTransaction.js +19 -0
- package/lib/bridge/createTransaction.js.map +1 -0
- package/lib/bridge/deviceTransactionConfig.d.ts +20 -0
- package/lib/bridge/deviceTransactionConfig.d.ts.map +1 -0
- package/lib/bridge/deviceTransactionConfig.js +65 -0
- package/lib/bridge/deviceTransactionConfig.js.map +1 -0
- package/lib/bridge/estimateMaxSpendable.d.ts +5 -0
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -0
- package/lib/bridge/estimateMaxSpendable.js +30 -0
- package/lib/bridge/estimateMaxSpendable.js.map +1 -0
- package/lib/bridge/getEstimateFees.d.ts +6 -0
- package/lib/bridge/getEstimateFees.d.ts.map +1 -0
- package/lib/bridge/getEstimateFees.js +52 -0
- package/lib/bridge/getEstimateFees.js.map +1 -0
- package/lib/bridge/getTransactionStatus.d.ts +4 -0
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -0
- package/lib/bridge/getTransactionStatus.js +218 -0
- package/lib/bridge/getTransactionStatus.js.map +1 -0
- package/lib/bridge/index.d.ts +10 -0
- package/lib/bridge/index.d.ts.map +1 -0
- package/lib/bridge/index.js +60 -0
- package/lib/bridge/index.js.map +1 -0
- package/lib/bridge/preload.d.ts +8 -0
- package/lib/bridge/preload.d.ts.map +1 -0
- package/lib/bridge/preload.js +32 -0
- package/lib/bridge/preload.js.map +1 -0
- package/lib/bridge/prepareTransaction.d.ts +4 -0
- package/lib/bridge/prepareTransaction.d.ts.map +1 -0
- package/lib/bridge/prepareTransaction.js +19 -0
- package/lib/bridge/prepareTransaction.js.map +1 -0
- package/lib/bridge/serialization.d.ts +9 -0
- package/lib/bridge/serialization.d.ts.map +1 -0
- package/lib/bridge/serialization.js +238 -0
- package/lib/bridge/serialization.js.map +1 -0
- package/lib/bridge/signOperation.d.ts +5 -0
- package/lib/bridge/signOperation.d.ts.map +1 -0
- package/lib/bridge/signOperation.js +92 -0
- package/lib/bridge/signOperation.js.map +1 -0
- package/lib/bridge/synchronization.d.ts +5 -0
- package/lib/bridge/synchronization.d.ts.map +1 -0
- package/lib/bridge/synchronization.integ.test.d.ts +3 -0
- package/lib/bridge/synchronization.integ.test.d.ts.map +1 -0
- package/lib/bridge/synchronization.integ.test.js +96 -0
- package/lib/bridge/synchronization.integ.test.js.map +1 -0
- package/lib/bridge/synchronization.js +216 -0
- package/lib/bridge/synchronization.js.map +1 -0
- package/lib/bridge/transaction.d.ts +15 -0
- package/lib/bridge/transaction.d.ts.map +1 -0
- package/lib/bridge/transaction.js +61 -0
- package/lib/bridge/transaction.js.map +1 -0
- package/lib/config.d.ts +10 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +17 -0
- package/lib/config.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +21 -0
- package/lib/index.js.map +1 -0
- package/lib/logic/constants.d.ts +4 -0
- package/lib/logic/constants.d.ts.map +1 -0
- package/lib/logic/constants.js +7 -0
- package/lib/logic/constants.js.map +1 -0
- package/lib/logic/pagination.d.ts +3 -0
- package/lib/logic/pagination.d.ts.map +1 -0
- package/lib/logic/pagination.js +19 -0
- package/lib/logic/pagination.js.map +1 -0
- package/lib/logic/utils.d.ts +12 -0
- package/lib/logic/utils.d.ts.map +1 -0
- package/lib/logic/utils.js +177 -0
- package/lib/logic/utils.js.map +1 -0
- package/lib/network/format.d.ts +9 -0
- package/lib/network/format.d.ts.map +1 -0
- package/lib/network/format.js +127 -0
- package/lib/network/format.js.map +1 -0
- package/lib/network/index.d.ts +30 -0
- package/lib/network/index.d.ts.map +1 -0
- package/lib/network/index.integ.test.d.ts +2 -0
- package/lib/network/index.integ.test.d.ts.map +1 -0
- package/lib/network/index.integ.test.js +38 -0
- package/lib/network/index.integ.test.js.map +1 -0
- package/lib/network/index.js +555 -0
- package/lib/network/index.js.map +1 -0
- package/lib/network/index.test.d.ts +2 -0
- package/lib/network/index.test.d.ts.map +1 -0
- package/lib/network/index.test.js +66 -0
- package/lib/network/index.test.js.map +1 -0
- package/lib/network/superRepresentativesData.mock.d.ts +69 -0
- package/lib/network/superRepresentativesData.mock.d.ts.map +1 -0
- package/lib/network/superRepresentativesData.mock.js +2208 -0
- package/lib/network/superRepresentativesData.mock.js.map +1 -0
- package/lib/network/types.d.ts +122 -0
- package/lib/network/types.d.ts.map +1 -0
- package/lib/network/types.fixture.d.ts +498 -0
- package/lib/network/types.fixture.d.ts.map +1 -0
- package/lib/network/types.fixture.js +4375 -0
- package/lib/network/types.fixture.js.map +1 -0
- package/lib/network/types.js +13 -0
- package/lib/network/types.js.map +1 -0
- package/lib/signer/getAddress.d.ts +6 -0
- package/lib/signer/getAddress.d.ts.map +1 -0
- package/lib/signer/getAddress.js +19 -0
- package/lib/signer/getAddress.js.map +1 -0
- package/lib/signer/index.d.ts +6 -0
- package/lib/signer/index.d.ts.map +1 -0
- package/lib/signer/index.js +11 -0
- package/lib/signer/index.js.map +1 -0
- package/lib/test/bot-deviceActions.d.ts +4 -0
- package/lib/test/bot-deviceActions.d.ts.map +1 -0
- package/lib/test/bot-deviceActions.js +103 -0
- package/lib/test/bot-deviceActions.js.map +1 -0
- package/lib/test/bot-specs.d.ts +7 -0
- package/lib/test/bot-specs.d.ts.map +1 -0
- package/lib/test/bot-specs.js +433 -0
- package/lib/test/bot-specs.js.map +1 -0
- package/lib/test/bridgeDatasetTest.d.ts +4 -0
- package/lib/test/bridgeDatasetTest.d.ts.map +1 -0
- package/lib/test/bridgeDatasetTest.js +1284 -0
- package/lib/test/bridgeDatasetTest.js.map +1 -0
- package/lib/test/cli.d.ts +52 -0
- package/lib/test/cli.d.ts.map +1 -0
- package/lib/test/cli.js +155 -0
- package/lib/test/cli.js.map +1 -0
- package/lib/test/index.d.ts +6 -0
- package/lib/test/index.d.ts.map +1 -0
- package/lib/test/index.js +26 -0
- package/lib/test/index.js.map +1 -0
- package/lib/types/bridge.d.ts +245 -0
- package/lib/types/bridge.d.ts.map +1 -0
- package/lib/types/bridge.js +16 -0
- package/lib/types/bridge.js.map +1 -0
- package/lib/types/errors.d.ts +49 -0
- package/lib/types/errors.d.ts.map +1 -0
- package/lib/types/errors.js +21 -0
- package/lib/types/errors.js.map +1 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +21 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/signer.d.ts +10 -0
- package/lib/types/signer.d.ts.map +1 -0
- package/lib/types/signer.js +3 -0
- package/lib/types/signer.js.map +1 -0
- package/lib-es/bridge/broadcast.d.ts +7 -0
- package/lib-es/bridge/broadcast.d.ts.map +1 -0
- package/lib-es/bridge/broadcast.js +24 -0
- package/lib-es/bridge/broadcast.js.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.d.ts +5 -0
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.js +94 -0
- package/lib-es/bridge/buildOptimisticOperation.js.map +1 -0
- package/lib-es/bridge/createTransaction.d.ts +4 -0
- package/lib-es/bridge/createTransaction.d.ts.map +1 -0
- package/lib-es/bridge/createTransaction.js +14 -0
- package/lib-es/bridge/createTransaction.js.map +1 -0
- package/lib-es/bridge/deviceTransactionConfig.d.ts +20 -0
- package/lib-es/bridge/deviceTransactionConfig.d.ts.map +1 -0
- package/lib-es/bridge/deviceTransactionConfig.js +63 -0
- package/lib-es/bridge/deviceTransactionConfig.js.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.d.ts +5 -0
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.js +25 -0
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -0
- package/lib-es/bridge/getEstimateFees.d.ts +6 -0
- package/lib-es/bridge/getEstimateFees.d.ts.map +1 -0
- package/lib-es/bridge/getEstimateFees.js +47 -0
- package/lib-es/bridge/getEstimateFees.js.map +1 -0
- package/lib-es/bridge/getTransactionStatus.d.ts +4 -0
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -0
- package/lib-es/bridge/getTransactionStatus.js +213 -0
- package/lib-es/bridge/getTransactionStatus.js.map +1 -0
- package/lib-es/bridge/index.d.ts +10 -0
- package/lib-es/bridge/index.d.ts.map +1 -0
- package/lib-es/bridge/index.js +53 -0
- package/lib-es/bridge/index.js.map +1 -0
- package/lib-es/bridge/preload.d.ts +8 -0
- package/lib-es/bridge/preload.d.ts.map +1 -0
- package/lib-es/bridge/preload.js +27 -0
- package/lib-es/bridge/preload.js.map +1 -0
- package/lib-es/bridge/prepareTransaction.d.ts +4 -0
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -0
- package/lib-es/bridge/prepareTransaction.js +15 -0
- package/lib-es/bridge/prepareTransaction.js.map +1 -0
- package/lib-es/bridge/serialization.d.ts +9 -0
- package/lib-es/bridge/serialization.d.ts.map +1 -0
- package/lib-es/bridge/serialization.js +229 -0
- package/lib-es/bridge/serialization.js.map +1 -0
- package/lib-es/bridge/signOperation.d.ts +5 -0
- package/lib-es/bridge/signOperation.d.ts.map +1 -0
- package/lib-es/bridge/signOperation.js +85 -0
- package/lib-es/bridge/signOperation.js.map +1 -0
- package/lib-es/bridge/synchronization.d.ts +5 -0
- package/lib-es/bridge/synchronization.d.ts.map +1 -0
- package/lib-es/bridge/synchronization.integ.test.d.ts +3 -0
- package/lib-es/bridge/synchronization.integ.test.d.ts.map +1 -0
- package/lib-es/bridge/synchronization.integ.test.js +89 -0
- package/lib-es/bridge/synchronization.integ.test.js.map +1 -0
- package/lib-es/bridge/synchronization.js +209 -0
- package/lib-es/bridge/synchronization.js.map +1 -0
- package/lib-es/bridge/transaction.d.ts +15 -0
- package/lib-es/bridge/transaction.d.ts.map +1 -0
- package/lib-es/bridge/transaction.js +55 -0
- package/lib-es/bridge/transaction.js.map +1 -0
- package/lib-es/config.d.ts +10 -0
- package/lib-es/config.d.ts.map +1 -0
- package/lib-es/config.js +12 -0
- package/lib-es/config.js.map +1 -0
- package/lib-es/index.d.ts +3 -0
- package/lib-es/index.d.ts.map +1 -0
- package/lib-es/index.js +3 -0
- package/lib-es/index.js.map +1 -0
- package/lib-es/logic/constants.d.ts +4 -0
- package/lib-es/logic/constants.d.ts.map +1 -0
- package/lib-es/logic/constants.js +4 -0
- package/lib-es/logic/constants.js.map +1 -0
- package/lib-es/logic/pagination.d.ts +3 -0
- package/lib-es/logic/pagination.d.ts.map +1 -0
- package/lib-es/logic/pagination.js +15 -0
- package/lib-es/logic/pagination.js.map +1 -0
- package/lib-es/logic/utils.d.ts +12 -0
- package/lib-es/logic/utils.d.ts.map +1 -0
- package/lib-es/logic/utils.js +167 -0
- package/lib-es/logic/utils.js.map +1 -0
- package/lib-es/network/format.d.ts +9 -0
- package/lib-es/network/format.d.ts.map +1 -0
- package/lib-es/network/format.js +117 -0
- package/lib-es/network/format.js.map +1 -0
- package/lib-es/network/index.d.ts +30 -0
- package/lib-es/network/index.d.ts.map +1 -0
- package/lib-es/network/index.integ.test.d.ts +2 -0
- package/lib-es/network/index.integ.test.d.ts.map +1 -0
- package/lib-es/network/index.integ.test.js +36 -0
- package/lib-es/network/index.integ.test.js.map +1 -0
- package/lib-es/network/index.js +524 -0
- package/lib-es/network/index.js.map +1 -0
- package/lib-es/network/index.test.d.ts +2 -0
- package/lib-es/network/index.test.d.ts.map +1 -0
- package/lib-es/network/index.test.js +63 -0
- package/lib-es/network/index.test.js.map +1 -0
- package/lib-es/network/superRepresentativesData.mock.d.ts +69 -0
- package/lib-es/network/superRepresentativesData.mock.d.ts.map +1 -0
- package/lib-es/network/superRepresentativesData.mock.js +2206 -0
- package/lib-es/network/superRepresentativesData.mock.js.map +1 -0
- package/lib-es/network/types.d.ts +122 -0
- package/lib-es/network/types.d.ts.map +1 -0
- package/lib-es/network/types.fixture.d.ts +498 -0
- package/lib-es/network/types.fixture.d.ts.map +1 -0
- package/lib-es/network/types.fixture.js +4371 -0
- package/lib-es/network/types.fixture.js.map +1 -0
- package/lib-es/network/types.js +8 -0
- package/lib-es/network/types.js.map +1 -0
- package/lib-es/signer/getAddress.d.ts +6 -0
- package/lib-es/signer/getAddress.d.ts.map +1 -0
- package/lib-es/signer/getAddress.js +17 -0
- package/lib-es/signer/getAddress.js.map +1 -0
- package/lib-es/signer/index.d.ts +6 -0
- package/lib-es/signer/index.d.ts.map +1 -0
- package/lib-es/signer/index.js +6 -0
- package/lib-es/signer/index.js.map +1 -0
- package/lib-es/test/bot-deviceActions.d.ts +4 -0
- package/lib-es/test/bot-deviceActions.d.ts.map +1 -0
- package/lib-es/test/bot-deviceActions.js +100 -0
- package/lib-es/test/bot-deviceActions.js.map +1 -0
- package/lib-es/test/bot-specs.d.ts +7 -0
- package/lib-es/test/bot-specs.d.ts.map +1 -0
- package/lib-es/test/bot-specs.js +428 -0
- package/lib-es/test/bot-specs.js.map +1 -0
- package/lib-es/test/bridgeDatasetTest.d.ts +4 -0
- package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -0
- package/lib-es/test/bridgeDatasetTest.js +1278 -0
- package/lib-es/test/bridgeDatasetTest.js.map +1 -0
- package/lib-es/test/cli.d.ts +52 -0
- package/lib-es/test/cli.d.ts.map +1 -0
- package/lib-es/test/cli.js +149 -0
- package/lib-es/test/cli.js.map +1 -0
- package/lib-es/test/index.d.ts +6 -0
- package/lib-es/test/index.d.ts.map +1 -0
- package/lib-es/test/index.js +6 -0
- package/lib-es/test/index.js.map +1 -0
- package/lib-es/types/bridge.d.ts +245 -0
- package/lib-es/types/bridge.d.ts.map +1 -0
- package/lib-es/types/bridge.js +11 -0
- package/lib-es/types/bridge.js.map +1 -0
- package/lib-es/types/errors.d.ts +49 -0
- package/lib-es/types/errors.d.ts.map +1 -0
- package/lib-es/types/errors.js +18 -0
- package/lib-es/types/errors.js.map +1 -0
- package/lib-es/types/index.d.ts +4 -0
- package/lib-es/types/index.d.ts.map +1 -0
- package/lib-es/types/index.js +5 -0
- package/lib-es/types/index.js.map +1 -0
- package/lib-es/types/signer.d.ts +10 -0
- package/lib-es/types/signer.d.ts.map +1 -0
- package/lib-es/types/signer.js +2 -0
- package/lib-es/types/signer.js.map +1 -0
- package/package.json +133 -0
- package/src/bridge/broadcast.ts +24 -0
- package/src/bridge/buildOptimisticOperation.ts +133 -0
- package/src/bridge/createTransaction.ts +16 -0
- package/src/bridge/deviceTransactionConfig.ts +99 -0
- package/src/bridge/estimateMaxSpendable.ts +32 -0
- package/src/bridge/getEstimateFees.ts +52 -0
- package/src/bridge/getTransactionStatus.ts +263 -0
- package/src/bridge/index.ts +78 -0
- package/src/bridge/preload.ts +24 -0
- package/src/bridge/prepareTransaction.ts +12 -0
- package/src/bridge/serialization.ts +288 -0
- package/src/bridge/signOperation.ts +123 -0
- package/src/bridge/synchronization.integ.test.ts +105 -0
- package/src/bridge/synchronization.ts +284 -0
- package/src/bridge/transaction.ts +84 -0
- package/src/config.ts +24 -0
- package/src/index.ts +3 -0
- package/src/logic/constants.ts +4 -0
- package/src/logic/pagination.ts +21 -0
- package/src/logic/utils.ts +231 -0
- package/src/network/format.ts +148 -0
- package/src/network/index.integ.test.ts +33 -0
- package/src/network/index.test.ts +61 -0
- package/src/network/index.ts +747 -0
- package/src/network/superRepresentativesData.mock.ts +2205 -0
- package/src/network/types.fixture.ts +4476 -0
- package/src/network/types.ts +147 -0
- package/src/signer/getAddress.ts +13 -0
- package/src/signer/index.ts +7 -0
- package/src/test/bot-deviceActions.ts +121 -0
- package/src/test/bot-specs.ts +457 -0
- package/src/test/bridgeDatasetTest.ts +1343 -0
- package/src/test/cli.ts +219 -0
- package/src/test/index.ts +6 -0
- package/src/types/bridge.ts +304 -0
- package/src/types/errors.ts +22 -0
- package/src/types/index.ts +4 -0
- package/src/types/signer.ts +9 -0
- package/tsconfig.json +14 -0
- package/types/tronweb/index.d.ts +5 -0
|
@@ -0,0 +1,747 @@
|
|
|
1
|
+
import { hours, makeLRUCache } from "@ledgerhq/live-network/cache";
|
|
2
|
+
import network from "@ledgerhq/live-network";
|
|
3
|
+
import { promiseAllBatched } from "@ledgerhq/live-promise";
|
|
4
|
+
import { log } from "@ledgerhq/logs";
|
|
5
|
+
import { Account, SubAccount, TokenAccount } from "@ledgerhq/types-live";
|
|
6
|
+
import { BigNumber } from "bignumber.js";
|
|
7
|
+
import compact from "lodash/compact";
|
|
8
|
+
import drop from "lodash/drop";
|
|
9
|
+
import get from "lodash/get";
|
|
10
|
+
import sumBy from "lodash/sumBy";
|
|
11
|
+
import take from "lodash/take";
|
|
12
|
+
import TronWeb from "tronweb";
|
|
13
|
+
import { TronTransactionExpired } from "../types/errors";
|
|
14
|
+
import { getCoinConfig } from "../config";
|
|
15
|
+
import {
|
|
16
|
+
abiEncodeTrc20Transfer,
|
|
17
|
+
defaultTronResources,
|
|
18
|
+
extractBandwidthInfo,
|
|
19
|
+
hexToAscii,
|
|
20
|
+
} from "../logic/utils";
|
|
21
|
+
import type {
|
|
22
|
+
FreezeTransactionData,
|
|
23
|
+
LegacyUnfreezeTransactionData,
|
|
24
|
+
NetworkInfo,
|
|
25
|
+
SendTransactionData,
|
|
26
|
+
SendTransactionDataSuccess,
|
|
27
|
+
SmartContractTransactionData,
|
|
28
|
+
SuperRepresentative,
|
|
29
|
+
SuperRepresentativeData,
|
|
30
|
+
Transaction,
|
|
31
|
+
TronResource,
|
|
32
|
+
TronResources,
|
|
33
|
+
TronTransactionInfo,
|
|
34
|
+
TrongridTxInfo,
|
|
35
|
+
UnDelegateResourceTransactionData,
|
|
36
|
+
UnFreezeTransactionData,
|
|
37
|
+
UnFrozenInfo,
|
|
38
|
+
WithdrawExpireUnfreezeTransactionData,
|
|
39
|
+
} from "../types";
|
|
40
|
+
import {
|
|
41
|
+
decode58Check,
|
|
42
|
+
encode58Check,
|
|
43
|
+
formatTrongridTrc20TxResponse,
|
|
44
|
+
formatTrongridTxResponse,
|
|
45
|
+
} from "./format";
|
|
46
|
+
import {
|
|
47
|
+
isMalformedTransactionTronAPI,
|
|
48
|
+
isTransactionTronAPI,
|
|
49
|
+
MalformedTransactionTronAPI,
|
|
50
|
+
TransactionResponseTronAPI,
|
|
51
|
+
TransactionTronAPI,
|
|
52
|
+
Trc20API,
|
|
53
|
+
} from "./types";
|
|
54
|
+
import { stringify } from "querystring";
|
|
55
|
+
|
|
56
|
+
const getBaseApiUrl = () => getCoinConfig().explorer.url;
|
|
57
|
+
|
|
58
|
+
async function post<T, U extends object = any>(endPoint: string, body: T): Promise<U> {
|
|
59
|
+
const { data } = await network<U, T>({
|
|
60
|
+
method: "POST",
|
|
61
|
+
url: `${getBaseApiUrl()}${endPoint}`,
|
|
62
|
+
data: body,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Ugly but trongrid send a 200 status event if there are errors
|
|
66
|
+
if ("Error" in data) {
|
|
67
|
+
log("tron-error", stringify(data.Error as any), {
|
|
68
|
+
endPoint,
|
|
69
|
+
body,
|
|
70
|
+
});
|
|
71
|
+
throw new Error(stringify(data.Error as any));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return data;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function fetch<T extends object = any>(endPoint: string): Promise<T> {
|
|
78
|
+
return fetchWithBaseUrl<T>(`${getBaseApiUrl()}${endPoint}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function fetchWithBaseUrl<T extends object = any>(url: string): Promise<T> {
|
|
82
|
+
const { data } = await network<T>({ url });
|
|
83
|
+
|
|
84
|
+
// Ugly but trongrid send a 200 status event if there are errors
|
|
85
|
+
if ("Error" in data) {
|
|
86
|
+
log("tron-error", stringify(data.Error as any), {
|
|
87
|
+
url,
|
|
88
|
+
});
|
|
89
|
+
throw new Error(stringify(data.Error as any));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export const freezeTronTransaction = async (
|
|
96
|
+
account: Account,
|
|
97
|
+
transaction: Transaction,
|
|
98
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
99
|
+
const txData: FreezeTransactionData = {
|
|
100
|
+
frozen_balance: transaction.amount.toNumber(),
|
|
101
|
+
resource: transaction.resource,
|
|
102
|
+
owner_address: decode58Check(account.freshAddress),
|
|
103
|
+
};
|
|
104
|
+
const url = `/wallet/freezebalancev2`;
|
|
105
|
+
const result = await post(url, txData);
|
|
106
|
+
|
|
107
|
+
return result;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export const unfreezeTronTransaction = async (
|
|
111
|
+
account: Account,
|
|
112
|
+
transaction: Transaction,
|
|
113
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
114
|
+
const txData: UnFreezeTransactionData = {
|
|
115
|
+
owner_address: decode58Check(account.freshAddress),
|
|
116
|
+
resource: transaction.resource,
|
|
117
|
+
unfreeze_balance: transaction.amount.toNumber(),
|
|
118
|
+
};
|
|
119
|
+
const url = `/wallet/unfreezebalancev2`;
|
|
120
|
+
const result = await post(url, txData);
|
|
121
|
+
|
|
122
|
+
return result;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const withdrawExpireUnfreezeTronTransaction = async (
|
|
126
|
+
account: Account,
|
|
127
|
+
_transaction: Transaction,
|
|
128
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
129
|
+
const txData: WithdrawExpireUnfreezeTransactionData = {
|
|
130
|
+
owner_address: decode58Check(account.freshAddress),
|
|
131
|
+
};
|
|
132
|
+
const url = `/wallet/withdrawexpireunfreeze`;
|
|
133
|
+
const result = await post(url, txData);
|
|
134
|
+
|
|
135
|
+
return result;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const unDelegateResourceTransaction = async (
|
|
139
|
+
account: Account,
|
|
140
|
+
transaction: Transaction,
|
|
141
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
142
|
+
const txData: UnDelegateResourceTransactionData = {
|
|
143
|
+
balance: transaction.amount.toNumber(),
|
|
144
|
+
resource: transaction.resource,
|
|
145
|
+
owner_address: decode58Check(account.freshAddress),
|
|
146
|
+
receiver_address: decode58Check(transaction.recipient),
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const url = `/wallet/undelegateresource`;
|
|
150
|
+
const result = await post(url, txData);
|
|
151
|
+
|
|
152
|
+
return result;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export const legacyUnfreezeTronTransaction = async (
|
|
156
|
+
account: Account,
|
|
157
|
+
transaction: Transaction,
|
|
158
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
159
|
+
const txData: LegacyUnfreezeTransactionData = {
|
|
160
|
+
resource: transaction.resource,
|
|
161
|
+
owner_address: decode58Check(account.freshAddress),
|
|
162
|
+
receiver_address: transaction.recipient ? decode58Check(transaction.recipient) : undefined,
|
|
163
|
+
};
|
|
164
|
+
const url = `/wallet/unfreezebalance`;
|
|
165
|
+
const result = await post(url, txData);
|
|
166
|
+
return result;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export async function getDelegatedResource(
|
|
170
|
+
account: Account,
|
|
171
|
+
transaction: Transaction,
|
|
172
|
+
resource: TronResource,
|
|
173
|
+
): Promise<BigNumber> {
|
|
174
|
+
const url = `/wallet/getdelegatedresourcev2`;
|
|
175
|
+
|
|
176
|
+
const {
|
|
177
|
+
delegatedResource = [],
|
|
178
|
+
}: {
|
|
179
|
+
delegatedResource?: {
|
|
180
|
+
frozen_balance_for_bandwidth: number;
|
|
181
|
+
frozen_balance_for_energy: number;
|
|
182
|
+
}[];
|
|
183
|
+
} = await post(url, {
|
|
184
|
+
fromAddress: decode58Check(account.freshAddress),
|
|
185
|
+
toAddress: decode58Check(transaction.recipient),
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const { frozen_balance_for_bandwidth, frozen_balance_for_energy } = delegatedResource.reduce(
|
|
189
|
+
(accum, cur) => {
|
|
190
|
+
if (cur.frozen_balance_for_bandwidth) {
|
|
191
|
+
accum.frozen_balance_for_bandwidth += cur.frozen_balance_for_bandwidth;
|
|
192
|
+
}
|
|
193
|
+
if (cur.frozen_balance_for_energy) {
|
|
194
|
+
accum.frozen_balance_for_energy += cur.frozen_balance_for_energy;
|
|
195
|
+
}
|
|
196
|
+
return accum;
|
|
197
|
+
},
|
|
198
|
+
{ frozen_balance_for_bandwidth: 0, frozen_balance_for_energy: 0 },
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const amount =
|
|
202
|
+
resource === "BANDWIDTH" ? frozen_balance_for_bandwidth : frozen_balance_for_energy;
|
|
203
|
+
|
|
204
|
+
return new BigNumber(amount);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Send trx or trc10/trc20 tokens
|
|
208
|
+
export const createTronTransaction = async (
|
|
209
|
+
account: Account,
|
|
210
|
+
transaction: Transaction,
|
|
211
|
+
subAccount: SubAccount | null | undefined,
|
|
212
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
213
|
+
const [tokenType, tokenId] =
|
|
214
|
+
subAccount && subAccount.type === "TokenAccount"
|
|
215
|
+
? drop(subAccount.token.id.split("/"), 1)
|
|
216
|
+
: [undefined, undefined];
|
|
217
|
+
|
|
218
|
+
// trc20
|
|
219
|
+
if (tokenType === "trc20" && tokenId) {
|
|
220
|
+
const tokenContractAddress = (subAccount as TokenAccount).token.contractAddress;
|
|
221
|
+
const txData: SmartContractTransactionData = {
|
|
222
|
+
function_selector: "transfer(address,uint256)",
|
|
223
|
+
fee_limit: 50000000,
|
|
224
|
+
call_value: 0,
|
|
225
|
+
contract_address: decode58Check(tokenContractAddress),
|
|
226
|
+
parameter: abiEncodeTrc20Transfer(decode58Check(transaction.recipient), transaction.amount),
|
|
227
|
+
owner_address: decode58Check(account.freshAddress),
|
|
228
|
+
};
|
|
229
|
+
const url = `/wallet/triggersmartcontract`;
|
|
230
|
+
const { transaction: preparedTransaction } = await post(url, txData);
|
|
231
|
+
return extendTronTxExpirationTimeBy10mn(preparedTransaction);
|
|
232
|
+
} else {
|
|
233
|
+
// trx/trc10
|
|
234
|
+
const txData: SendTransactionData = {
|
|
235
|
+
to_address: decode58Check(transaction.recipient),
|
|
236
|
+
owner_address: decode58Check(account.freshAddress),
|
|
237
|
+
amount: transaction.amount.toNumber(),
|
|
238
|
+
asset_name: tokenId && Buffer.from(tokenId).toString("hex"),
|
|
239
|
+
};
|
|
240
|
+
const url = subAccount ? `/wallet/transferasset` : `/wallet/createtransaction`;
|
|
241
|
+
const preparedTransaction = await post(url, txData);
|
|
242
|
+
// for the ledger Vault we need to increase the expiration
|
|
243
|
+
return extendTronTxExpirationTimeBy10mn(preparedTransaction);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
function extendTronTxExpirationTimeBy10mn(
|
|
248
|
+
preparedTransaction: any,
|
|
249
|
+
): Promise<SendTransactionDataSuccess> {
|
|
250
|
+
const VAULT_EXPIRATION_TIME = 600;
|
|
251
|
+
const HttpProvider = TronWeb.providers.HttpProvider;
|
|
252
|
+
const fullNode = new HttpProvider(getBaseApiUrl());
|
|
253
|
+
const solidityNode = new HttpProvider(getBaseApiUrl());
|
|
254
|
+
const eventServer = new HttpProvider(getBaseApiUrl());
|
|
255
|
+
const tronWeb = new TronWeb(fullNode, solidityNode, eventServer);
|
|
256
|
+
//FIXME: test it and rewrite it
|
|
257
|
+
return tronWeb.transactionBuilder.extendExpiration(
|
|
258
|
+
preparedTransaction,
|
|
259
|
+
VAULT_EXPIRATION_TIME,
|
|
260
|
+
) as unknown as Promise<SendTransactionDataSuccess>;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export const broadcastTron = async (trxTransaction: SendTransactionDataSuccess) => {
|
|
264
|
+
const result = await post(`/wallet/broadcasttransaction`, trxTransaction);
|
|
265
|
+
|
|
266
|
+
if (result.code === "TRANSACTION_EXPIRATION_ERROR") {
|
|
267
|
+
throw new TronTransactionExpired();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return result;
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
export async function fetchTronAccount(addr: string) {
|
|
274
|
+
try {
|
|
275
|
+
const data = await fetch(`/v1/accounts/${addr}`);
|
|
276
|
+
return data.data;
|
|
277
|
+
} catch (e) {
|
|
278
|
+
return [];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export async function fetchCurrentBlockHeight() {
|
|
283
|
+
const data = await fetch(`/wallet/getnowblock`);
|
|
284
|
+
return data.block_header.raw_data.number;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// For the moment, fetching transaction info is the only way to get fees from a transaction
|
|
288
|
+
async function fetchTronTxDetail(txId: string): Promise<TronTransactionInfo> {
|
|
289
|
+
const { fee, blockNumber, withdraw_amount, unfreeze_amount } = await fetch(
|
|
290
|
+
`/wallet/gettransactioninfobyid?value=${encodeURIComponent(txId)}`,
|
|
291
|
+
);
|
|
292
|
+
return {
|
|
293
|
+
fee,
|
|
294
|
+
blockNumber,
|
|
295
|
+
withdraw_amount,
|
|
296
|
+
unfreeze_amount,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
async function getAllTransactions<T>(
|
|
301
|
+
initialUrl: string,
|
|
302
|
+
shouldFetchMoreTxs: (txs: T[]) => boolean,
|
|
303
|
+
getTxs: (url: string) => Promise<{
|
|
304
|
+
results: Array<T>;
|
|
305
|
+
nextUrl?: string;
|
|
306
|
+
}>,
|
|
307
|
+
) {
|
|
308
|
+
let all: Array<T> = [];
|
|
309
|
+
let url: string | undefined = initialUrl;
|
|
310
|
+
|
|
311
|
+
while (url && shouldFetchMoreTxs(all)) {
|
|
312
|
+
const { nextUrl, results } = await getTxs(url);
|
|
313
|
+
url = nextUrl;
|
|
314
|
+
all = all.concat(results);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return all;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const getTransactions =
|
|
321
|
+
(cacheTransactionInfoById: Record<string, TronTransactionInfo>) =>
|
|
322
|
+
async (
|
|
323
|
+
url: string,
|
|
324
|
+
): Promise<{
|
|
325
|
+
results: Array<
|
|
326
|
+
(TransactionTronAPI & { detail?: TronTransactionInfo }) | MalformedTransactionTronAPI
|
|
327
|
+
>;
|
|
328
|
+
nextUrl?: string;
|
|
329
|
+
}> => {
|
|
330
|
+
const transactions =
|
|
331
|
+
await fetchWithBaseUrl<
|
|
332
|
+
TransactionResponseTronAPI<TransactionTronAPI | MalformedTransactionTronAPI>
|
|
333
|
+
>(url);
|
|
334
|
+
|
|
335
|
+
const nextUrl = transactions.meta.links?.next;
|
|
336
|
+
const results = await promiseAllBatched(3, transactions.data || [], async tx => {
|
|
337
|
+
if (isMalformedTransactionTronAPI(tx)) {
|
|
338
|
+
return tx;
|
|
339
|
+
}
|
|
340
|
+
const txID = tx.txID;
|
|
341
|
+
|
|
342
|
+
const detail = cacheTransactionInfoById[txID] || (await fetchTronTxDetail(txID));
|
|
343
|
+
cacheTransactionInfoById[txID] = detail;
|
|
344
|
+
return { ...tx, detail };
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
results,
|
|
349
|
+
nextUrl,
|
|
350
|
+
};
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const getTrc20 = async (
|
|
354
|
+
url: string,
|
|
355
|
+
): Promise<{
|
|
356
|
+
results: Array<Trc20API>;
|
|
357
|
+
nextUrl?: string;
|
|
358
|
+
}> => {
|
|
359
|
+
const transactions = await fetchWithBaseUrl<TransactionResponseTronAPI<Trc20API>>(url);
|
|
360
|
+
|
|
361
|
+
return {
|
|
362
|
+
results: transactions.data,
|
|
363
|
+
nextUrl: transactions.meta.links?.next,
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
export async function fetchTronAccountTxs(
|
|
368
|
+
addr: string,
|
|
369
|
+
shouldFetchMoreTxs: (
|
|
370
|
+
txs: Array<TransactionTronAPI | Trc20API | MalformedTransactionTronAPI>,
|
|
371
|
+
) => boolean,
|
|
372
|
+
cacheTransactionInfoById: Record<string, TronTransactionInfo>,
|
|
373
|
+
): Promise<TrongridTxInfo[]> {
|
|
374
|
+
const entireTxs = (
|
|
375
|
+
await getAllTransactions<
|
|
376
|
+
(TransactionTronAPI & { detail?: TronTransactionInfo }) | MalformedTransactionTronAPI
|
|
377
|
+
>(
|
|
378
|
+
`${getBaseApiUrl()}/v1/accounts/${addr}/transactions?limit=100`,
|
|
379
|
+
shouldFetchMoreTxs,
|
|
380
|
+
getTransactions(cacheTransactionInfoById),
|
|
381
|
+
)
|
|
382
|
+
)
|
|
383
|
+
.filter((tx): tx is TransactionTronAPI => isTransactionTronAPI(tx))
|
|
384
|
+
.filter(tx => {
|
|
385
|
+
// custom smart contract tx has internal txs
|
|
386
|
+
const hasInternalTxs =
|
|
387
|
+
tx.txID && tx.internal_transactions && tx.internal_transactions.length > 0;
|
|
388
|
+
// and also a duplicated malformed tx that we have to ignore
|
|
389
|
+
const isDuplicated = tx.tx_id;
|
|
390
|
+
const type = tx.raw_data.contract[0].type;
|
|
391
|
+
|
|
392
|
+
if (hasInternalTxs) {
|
|
393
|
+
// log once
|
|
394
|
+
log("tron-error", `unsupported transaction ${tx.txID}`);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return !isDuplicated && !hasInternalTxs && type !== "TriggerSmartContract";
|
|
398
|
+
})
|
|
399
|
+
.map(tx => formatTrongridTxResponse(tx));
|
|
400
|
+
|
|
401
|
+
// we need to fetch and filter trc20 transactions from another endpoint
|
|
402
|
+
const entireTrc20Txs = (
|
|
403
|
+
await getAllTransactions<Trc20API>(
|
|
404
|
+
`${getBaseApiUrl()}/v1/accounts/${addr}/transactions/trc20?get_detail=true`,
|
|
405
|
+
shouldFetchMoreTxs,
|
|
406
|
+
getTrc20,
|
|
407
|
+
)
|
|
408
|
+
).map(tx => formatTrongridTrc20TxResponse(tx));
|
|
409
|
+
|
|
410
|
+
const txInfos: TrongridTxInfo[] = compact(entireTxs.concat(entireTrc20Txs)).sort(
|
|
411
|
+
(a, b) => b.date.getTime() - a.date.getTime(),
|
|
412
|
+
);
|
|
413
|
+
return txInfos;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export const getContractUserEnergyRatioConsumption = async (address: string): Promise<number> => {
|
|
417
|
+
const result = await fetchTronContract(address);
|
|
418
|
+
if (result) {
|
|
419
|
+
const { consume_user_resource_percent } = result;
|
|
420
|
+
return consume_user_resource_percent;
|
|
421
|
+
}
|
|
422
|
+
return 0;
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
export const fetchTronContract = async (addr: string): Promise<Record<string, any> | undefined> => {
|
|
426
|
+
try {
|
|
427
|
+
const data = await post(`/wallet/getcontract`, {
|
|
428
|
+
value: decode58Check(addr),
|
|
429
|
+
});
|
|
430
|
+
return Object.keys(data).length !== 0 ? data : undefined;
|
|
431
|
+
} catch (e) {
|
|
432
|
+
return undefined;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
export const getTronAccountNetwork = async (address: string): Promise<NetworkInfo> => {
|
|
437
|
+
const result = await fetch(
|
|
438
|
+
`/wallet/getaccountresource?address=${encodeURIComponent(decode58Check(address))}`,
|
|
439
|
+
);
|
|
440
|
+
const {
|
|
441
|
+
freeNetUsed = 0,
|
|
442
|
+
freeNetLimit = 0,
|
|
443
|
+
NetUsed = 0,
|
|
444
|
+
NetLimit = 0,
|
|
445
|
+
EnergyUsed = 0,
|
|
446
|
+
EnergyLimit = 0,
|
|
447
|
+
} = result;
|
|
448
|
+
return {
|
|
449
|
+
family: "tron",
|
|
450
|
+
freeNetUsed: new BigNumber(freeNetUsed),
|
|
451
|
+
freeNetLimit: new BigNumber(freeNetLimit),
|
|
452
|
+
netUsed: new BigNumber(NetUsed),
|
|
453
|
+
netLimit: new BigNumber(NetLimit),
|
|
454
|
+
energyUsed: new BigNumber(EnergyUsed),
|
|
455
|
+
energyLimit: new BigNumber(EnergyLimit),
|
|
456
|
+
};
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
export const validateAddress = async (address: string): Promise<boolean> => {
|
|
460
|
+
try {
|
|
461
|
+
const result = await post(`/wallet/validateaddress`, {
|
|
462
|
+
address: decode58Check(address),
|
|
463
|
+
});
|
|
464
|
+
return result.result || false;
|
|
465
|
+
} catch (e: any) {
|
|
466
|
+
// FIXME we should not silent errors!
|
|
467
|
+
log("tron-error", "validateAddress fails with " + e.message, {
|
|
468
|
+
address,
|
|
469
|
+
});
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
// cache for account names (name is unchanged over time)
|
|
475
|
+
const accountNamesCache = makeLRUCache(
|
|
476
|
+
async (addr: string): Promise<string | null | undefined> => getAccountName(addr),
|
|
477
|
+
(addr: string) => addr,
|
|
478
|
+
hours(3, 300),
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
// cache for super representative brokerages (brokerage is unchanged over time)
|
|
482
|
+
const srBrokeragesCache = makeLRUCache(
|
|
483
|
+
async (addr: string): Promise<number> => getBrokerage(addr),
|
|
484
|
+
(addr: string) => addr,
|
|
485
|
+
hours(3, 300),
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
export const getAccountName = async (addr: string): Promise<string | null | undefined> => {
|
|
489
|
+
const tronAcc = await fetchTronAccount(addr);
|
|
490
|
+
const acc = tronAcc[0];
|
|
491
|
+
const accountName: string | null | undefined =
|
|
492
|
+
acc && acc.account_name ? hexToAscii(acc.account_name) : undefined;
|
|
493
|
+
accountNamesCache.hydrate(addr, accountName); // put it in cache
|
|
494
|
+
|
|
495
|
+
return accountName;
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
export const getBrokerage = async (addr: string): Promise<number> => {
|
|
499
|
+
const { brokerage } = await fetch(`/wallet/getBrokerage?address=${encodeURIComponent(addr)}`);
|
|
500
|
+
srBrokeragesCache.hydrate(addr, brokerage); // put it in cache
|
|
501
|
+
|
|
502
|
+
return brokerage;
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
const superRepresentativesCache = makeLRUCache(
|
|
506
|
+
async (): Promise<SuperRepresentative[]> => {
|
|
507
|
+
const superRepresentatives = await fetchSuperRepresentatives();
|
|
508
|
+
log(
|
|
509
|
+
"tron/superRepresentatives",
|
|
510
|
+
"loaded " + superRepresentatives.length + " super representatives",
|
|
511
|
+
);
|
|
512
|
+
return superRepresentatives;
|
|
513
|
+
},
|
|
514
|
+
() => "",
|
|
515
|
+
hours(1, 300),
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
export const getTronSuperRepresentatives = async (): Promise<SuperRepresentative[]> => {
|
|
519
|
+
return await superRepresentativesCache();
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
export const hydrateSuperRepresentatives = (list: SuperRepresentative[]) => {
|
|
523
|
+
log("tron/superRepresentatives", "hydrate " + list.length + " super representatives");
|
|
524
|
+
superRepresentativesCache.hydrate("", list);
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
const fetchSuperRepresentatives = async (): Promise<SuperRepresentative[]> => {
|
|
528
|
+
const result = await fetch(`/wallet/listwitnesses`);
|
|
529
|
+
const sorted = result.witnesses.sort((a: any, b: any) => b.voteCount - a.voteCount);
|
|
530
|
+
const superRepresentatives = await promiseAllBatched(3, sorted, async (w: any) => {
|
|
531
|
+
const encodedAddress = encode58Check(w.address);
|
|
532
|
+
const accountName = await accountNamesCache(encodedAddress);
|
|
533
|
+
const brokerage = await srBrokeragesCache(encodedAddress);
|
|
534
|
+
return {
|
|
535
|
+
...w,
|
|
536
|
+
address: encodedAddress,
|
|
537
|
+
name: accountName,
|
|
538
|
+
brokerage,
|
|
539
|
+
voteCount: w.voteCount || 0,
|
|
540
|
+
isJobs: w.isJobs || false,
|
|
541
|
+
};
|
|
542
|
+
});
|
|
543
|
+
hydrateSuperRepresentatives(superRepresentatives); // put it in cache
|
|
544
|
+
|
|
545
|
+
return superRepresentatives;
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
export const getNextVotingDate = async (): Promise<Date> => {
|
|
549
|
+
const { num } = await fetch(`/wallet/getnextmaintenancetime`);
|
|
550
|
+
return new Date(num);
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
export const getTronSuperRepresentativeData = async (
|
|
554
|
+
max: number | null | undefined,
|
|
555
|
+
): Promise<SuperRepresentativeData> => {
|
|
556
|
+
const list = await getTronSuperRepresentatives();
|
|
557
|
+
const nextVotingDate = await getNextVotingDate();
|
|
558
|
+
return {
|
|
559
|
+
list: max ? take(list, max) : list,
|
|
560
|
+
totalVotes: sumBy(list, "voteCount"),
|
|
561
|
+
nextVotingDate,
|
|
562
|
+
};
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
export const voteTronSuperRepresentatives = async (
|
|
566
|
+
account: Account,
|
|
567
|
+
transaction: Transaction,
|
|
568
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
569
|
+
const payload = {
|
|
570
|
+
owner_address: decode58Check(account.freshAddress),
|
|
571
|
+
votes: transaction.votes.map(v => ({
|
|
572
|
+
vote_address: decode58Check(v.address),
|
|
573
|
+
vote_count: v.voteCount,
|
|
574
|
+
})),
|
|
575
|
+
};
|
|
576
|
+
return await post(`/wallet/votewitnessaccount`, payload);
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
export async function getTronResources(
|
|
580
|
+
acc?: Record<string, any>,
|
|
581
|
+
txs?: TrongridTxInfo[],
|
|
582
|
+
cacheTransactionInfoById: Record<string, TronTransactionInfo> = {},
|
|
583
|
+
): Promise<TronResources> {
|
|
584
|
+
if (!acc) {
|
|
585
|
+
return defaultTronResources;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const delegatedFrozenBandwidth = get(acc, "delegated_frozenV2_balance_for_bandwidth", undefined);
|
|
589
|
+
const delegatedFrozenEnergy = get(
|
|
590
|
+
acc,
|
|
591
|
+
"account_resource.delegated_frozenV2_balance_for_energy",
|
|
592
|
+
undefined,
|
|
593
|
+
);
|
|
594
|
+
|
|
595
|
+
const frozenBalances: { type?: string; amount?: number }[] = get(acc, "frozenV2", undefined);
|
|
596
|
+
|
|
597
|
+
const legacyFrozenBandwidth = get(acc, "frozen[0]", undefined);
|
|
598
|
+
const legacyFrozenEnergy = get(acc, "account_resource.frozen_balance_for_energy", undefined);
|
|
599
|
+
|
|
600
|
+
const legacyFrozen = {
|
|
601
|
+
bandwidth: legacyFrozenBandwidth
|
|
602
|
+
? {
|
|
603
|
+
amount: new BigNumber(legacyFrozenBandwidth.frozen_balance),
|
|
604
|
+
expiredAt: new Date(legacyFrozenBandwidth.expire_time),
|
|
605
|
+
}
|
|
606
|
+
: undefined,
|
|
607
|
+
energy: legacyFrozenEnergy
|
|
608
|
+
? {
|
|
609
|
+
amount: new BigNumber(legacyFrozenEnergy.frozen_balance),
|
|
610
|
+
expiredAt: new Date(legacyFrozenEnergy.expire_time),
|
|
611
|
+
}
|
|
612
|
+
: undefined,
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
const { frozenEnergy, frozenBandwidth } = frozenBalances.reduce(
|
|
616
|
+
(accum, cur) => {
|
|
617
|
+
const amount = new BigNumber(cur?.amount ?? 0);
|
|
618
|
+
if (cur.type === "ENERGY") {
|
|
619
|
+
accum.frozenEnergy = accum.frozenEnergy.plus(amount);
|
|
620
|
+
} else if (cur.type === undefined) {
|
|
621
|
+
accum.frozenBandwidth = accum.frozenBandwidth.plus(amount);
|
|
622
|
+
}
|
|
623
|
+
return accum;
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
frozenEnergy: new BigNumber(0),
|
|
627
|
+
frozenBandwidth: new BigNumber(0),
|
|
628
|
+
},
|
|
629
|
+
);
|
|
630
|
+
|
|
631
|
+
const unFrozenBalances: {
|
|
632
|
+
type: string;
|
|
633
|
+
unfreeze_amount: number;
|
|
634
|
+
unfreeze_expire_time: number;
|
|
635
|
+
}[] = get(acc, "unfrozenV2", undefined);
|
|
636
|
+
|
|
637
|
+
const unFrozen: { bandwidth: UnFrozenInfo[]; energy: UnFrozenInfo[] } = unFrozenBalances
|
|
638
|
+
? unFrozenBalances.reduce(
|
|
639
|
+
(accum, cur) => {
|
|
640
|
+
if (cur && cur.type === "ENERGY") {
|
|
641
|
+
accum.energy.push({
|
|
642
|
+
amount: new BigNumber(cur.unfreeze_amount),
|
|
643
|
+
expireTime: new Date(cur.unfreeze_expire_time),
|
|
644
|
+
});
|
|
645
|
+
} else if (cur) {
|
|
646
|
+
accum.bandwidth.push({
|
|
647
|
+
amount: new BigNumber(cur.unfreeze_amount),
|
|
648
|
+
expireTime: new Date(cur.unfreeze_expire_time),
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
return accum;
|
|
652
|
+
},
|
|
653
|
+
{ bandwidth: [] as UnFrozenInfo[], energy: [] as UnFrozenInfo[] },
|
|
654
|
+
)
|
|
655
|
+
: { bandwidth: [], energy: [] };
|
|
656
|
+
|
|
657
|
+
const encodedAddress = encode58Check(acc.address);
|
|
658
|
+
const tronNetworkInfo = await getTronAccountNetwork(encodedAddress);
|
|
659
|
+
const unwithdrawnReward = await getUnwithdrawnReward(encodedAddress);
|
|
660
|
+
const energy = tronNetworkInfo.energyLimit.minus(tronNetworkInfo.energyUsed);
|
|
661
|
+
const bandwidth = extractBandwidthInfo(tronNetworkInfo);
|
|
662
|
+
|
|
663
|
+
const frozen = {
|
|
664
|
+
bandwidth: frozenBandwidth.isGreaterThan(0)
|
|
665
|
+
? {
|
|
666
|
+
amount: frozenBandwidth,
|
|
667
|
+
}
|
|
668
|
+
: undefined,
|
|
669
|
+
energy: frozenEnergy.isGreaterThan(0)
|
|
670
|
+
? {
|
|
671
|
+
amount: frozenEnergy,
|
|
672
|
+
}
|
|
673
|
+
: undefined,
|
|
674
|
+
};
|
|
675
|
+
const delegatedFrozen = {
|
|
676
|
+
bandwidth: delegatedFrozenBandwidth
|
|
677
|
+
? {
|
|
678
|
+
amount: new BigNumber(delegatedFrozenBandwidth),
|
|
679
|
+
}
|
|
680
|
+
: undefined,
|
|
681
|
+
energy: delegatedFrozenEnergy
|
|
682
|
+
? {
|
|
683
|
+
amount: new BigNumber(delegatedFrozenEnergy),
|
|
684
|
+
}
|
|
685
|
+
: undefined,
|
|
686
|
+
};
|
|
687
|
+
const tronPower = new BigNumber(get(frozen, "bandwidth.amount", 0))
|
|
688
|
+
.plus(get(frozen, "energy.amount", 0))
|
|
689
|
+
.plus(get(delegatedFrozen, "bandwidth.amount", 0))
|
|
690
|
+
.plus(get(delegatedFrozen, "energy.amount", 0))
|
|
691
|
+
.plus(get(legacyFrozen, "energy.amount", 0))
|
|
692
|
+
.plus(get(legacyFrozen, "bandwidth.amount", 0))
|
|
693
|
+
.dividedBy(1000000)
|
|
694
|
+
.integerValue(BigNumber.ROUND_FLOOR)
|
|
695
|
+
.toNumber();
|
|
696
|
+
const votes = get(acc, "votes", []).map((v: any) => ({
|
|
697
|
+
address: v.vote_address,
|
|
698
|
+
voteCount: v.vote_count,
|
|
699
|
+
}));
|
|
700
|
+
const lastWithdrawnRewardDate = acc.latest_withdraw_time
|
|
701
|
+
? new Date(acc.latest_withdraw_time)
|
|
702
|
+
: undefined;
|
|
703
|
+
|
|
704
|
+
// TODO: rely on the account object when trongrid will provide this info.
|
|
705
|
+
const getLastVotedDate = (txs: TrongridTxInfo[]): Date | null | undefined => {
|
|
706
|
+
const lastOp = txs.find(({ type }) => type === "VoteWitnessContract");
|
|
707
|
+
return lastOp ? lastOp.date : null;
|
|
708
|
+
};
|
|
709
|
+
const lastVotedDate = txs ? getLastVotedDate(txs) : undefined;
|
|
710
|
+
|
|
711
|
+
return {
|
|
712
|
+
energy,
|
|
713
|
+
bandwidth,
|
|
714
|
+
frozen,
|
|
715
|
+
unFrozen,
|
|
716
|
+
delegatedFrozen,
|
|
717
|
+
legacyFrozen,
|
|
718
|
+
votes,
|
|
719
|
+
tronPower,
|
|
720
|
+
unwithdrawnReward,
|
|
721
|
+
lastWithdrawnRewardDate,
|
|
722
|
+
lastVotedDate,
|
|
723
|
+
cacheTransactionInfoById,
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
export const getUnwithdrawnReward = async (addr: string): Promise<BigNumber> => {
|
|
728
|
+
try {
|
|
729
|
+
const { reward = 0 } = await fetch(
|
|
730
|
+
`/wallet/getReward?address=${encodeURIComponent(decode58Check(addr))}`,
|
|
731
|
+
);
|
|
732
|
+
return new BigNumber(reward);
|
|
733
|
+
} catch (e) {
|
|
734
|
+
return Promise.resolve(new BigNumber(0));
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
export const claimRewardTronTransaction = async (
|
|
739
|
+
account: Account,
|
|
740
|
+
): Promise<SendTransactionDataSuccess> => {
|
|
741
|
+
const url = `/wallet/withdrawbalance`;
|
|
742
|
+
const data = {
|
|
743
|
+
owner_address: decode58Check(account.freshAddress),
|
|
744
|
+
};
|
|
745
|
+
const result = await post(url, data);
|
|
746
|
+
return result;
|
|
747
|
+
};
|