@ledgerhq/coin-vechain 2.2.0-next.0
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 +74 -0
- package/CHANGELOG.md +1186 -0
- package/LICENSE.txt +21 -0
- package/jest.config.js +8 -0
- package/lib/account.d.ts +7 -0
- package/lib/account.d.ts.map +1 -0
- package/lib/account.js +19 -0
- package/lib/account.js.map +1 -0
- package/lib/bridge/broadcast.d.ts +8 -0
- package/lib/bridge/broadcast.d.ts.map +1 -0
- package/lib/bridge/broadcast.js +27 -0
- package/lib/bridge/broadcast.js.map +1 -0
- package/lib/bridge/buildOptimisticOperatioin.d.ts +4 -0
- package/lib/bridge/buildOptimisticOperatioin.d.ts.map +1 -0
- package/lib/bridge/buildOptimisticOperatioin.js +56 -0
- package/lib/bridge/buildOptimisticOperatioin.js.map +1 -0
- package/lib/bridge/createTransaction.d.ts +9 -0
- package/lib/bridge/createTransaction.d.ts.map +1 -0
- package/lib/bridge/createTransaction.js +36 -0
- package/lib/bridge/createTransaction.js.map +1 -0
- package/lib/bridge/estimateMaxSpendable.d.ts +4 -0
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -0
- package/lib/bridge/estimateMaxSpendable.js +29 -0
- package/lib/bridge/estimateMaxSpendable.js.map +1 -0
- package/lib/bridge/getTransactionStatus.d.ts +5 -0
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -0
- package/lib/bridge/getTransactionStatus.js +76 -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 +64 -0
- package/lib/bridge/index.js.map +1 -0
- package/lib/bridge/prepareTransaction.d.ts +10 -0
- package/lib/bridge/prepareTransaction.d.ts.map +1 -0
- package/lib/bridge/prepareTransaction.js +38 -0
- package/lib/bridge/prepareTransaction.js.map +1 -0
- package/lib/bridge/signOperation.d.ts +8 -0
- package/lib/bridge/signOperation.d.ts.map +1 -0
- package/lib/bridge/signOperation.js +43 -0
- package/lib/bridge/signOperation.js.map +1 -0
- package/lib/bridge/synchronisation.d.ts +4 -0
- package/lib/bridge/synchronisation.d.ts.map +1 -0
- package/lib/bridge/synchronisation.js +84 -0
- package/lib/bridge/synchronisation.js.map +1 -0
- package/lib/bridge/transaction.d.ts +17 -0
- package/lib/bridge/transaction.d.ts.map +1 -0
- package/lib/bridge/transaction.js +56 -0
- package/lib/bridge/transaction.js.map +1 -0
- package/lib/common-logic/address-utils.d.ts +2 -0
- package/lib/common-logic/address-utils.d.ts.map +1 -0
- package/lib/common-logic/address-utils.js +19 -0
- package/lib/common-logic/address-utils.js.map +1 -0
- package/lib/common-logic/hex-utils.d.ts +8 -0
- package/lib/common-logic/hex-utils.d.ts.map +1 -0
- package/lib/common-logic/hex-utils.js +52 -0
- package/lib/common-logic/hex-utils.js.map +1 -0
- package/lib/common-logic/index.d.ts +7 -0
- package/lib/common-logic/index.d.ts.map +1 -0
- package/lib/common-logic/index.js +23 -0
- package/lib/common-logic/index.js.map +1 -0
- package/lib/common-logic/logic.d.ts +5 -0
- package/lib/common-logic/logic.d.ts.map +1 -0
- package/lib/common-logic/logic.js +46 -0
- package/lib/common-logic/logic.js.map +1 -0
- package/lib/common-logic/mapping-utils.d.ts +5 -0
- package/lib/common-logic/mapping-utils.d.ts.map +1 -0
- package/lib/common-logic/mapping-utils.js +61 -0
- package/lib/common-logic/mapping-utils.js.map +1 -0
- package/lib/common-logic/pad-address.d.ts +2 -0
- package/lib/common-logic/pad-address.d.ts.map +1 -0
- package/lib/common-logic/pad-address.js +13 -0
- package/lib/common-logic/pad-address.js.map +1 -0
- package/lib/common-logic/transaction-utils.d.ts +30 -0
- package/lib/common-logic/transaction-utils.d.ts.map +1 -0
- package/lib/common-logic/transaction-utils.js +164 -0
- package/lib/common-logic/transaction-utils.js.map +1 -0
- package/lib/config.d.ts +5 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +17 -0
- package/lib/config.js.map +1 -0
- package/lib/contracts/abis/VIP180.d.ts +17 -0
- package/lib/contracts/abis/VIP180.d.ts.map +1 -0
- package/lib/contracts/abis/VIP180.js +265 -0
- package/lib/contracts/abis/VIP180.js.map +1 -0
- package/lib/contracts/abis/params.d.ts +8 -0
- package/lib/contracts/abis/params.d.ts.map +1 -0
- package/lib/contracts/abis/params.js +69 -0
- package/lib/contracts/abis/params.js.map +1 -0
- package/lib/contracts/constants.d.ts +6 -0
- package/lib/contracts/constants.d.ts.map +1 -0
- package/lib/contracts/constants.js +10 -0
- package/lib/contracts/constants.js.map +1 -0
- package/lib/datasets/index.d.ts +3 -0
- package/lib/datasets/index.d.ts.map +1 -0
- package/lib/datasets/index.js +23 -0
- package/lib/datasets/index.js.map +1 -0
- package/lib/datasets/vechain.d.ts +5 -0
- package/lib/datasets/vechain.d.ts.map +1 -0
- package/lib/datasets/vechain.js +91 -0
- package/lib/datasets/vechain.js.map +1 -0
- package/lib/datasets/vechain.scanAccounts.1.d.ts +6 -0
- package/lib/datasets/vechain.scanAccounts.1.d.ts.map +1 -0
- package/lib/datasets/vechain.scanAccounts.1.js +16 -0
- package/lib/datasets/vechain.scanAccounts.1.js.map +1 -0
- package/lib/errors.d.ts +10 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +8 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +6 -0
- package/lib/index.js.map +1 -0
- package/lib/mock.d.ts +9 -0
- package/lib/mock.d.ts.map +1 -0
- package/lib/mock.js +13 -0
- package/lib/mock.js.map +1 -0
- package/lib/network/index.d.ts +3 -0
- package/lib/network/index.d.ts.map +1 -0
- package/lib/network/index.js +22 -0
- package/lib/network/index.js.map +1 -0
- package/lib/network/sdk.d.ts +47 -0
- package/lib/network/sdk.d.ts.map +1 -0
- package/lib/network/sdk.js +164 -0
- package/lib/network/sdk.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 +32 -0
- package/lib/signer/getAddress.js.map +1 -0
- package/lib/signer/index.d.ts +4 -0
- package/lib/signer/index.d.ts.map +1 -0
- package/lib/signer/index.js +23 -0
- package/lib/signer/index.js.map +1 -0
- package/lib/signer/signMessage.d.ts +4 -0
- package/lib/signer/signMessage.d.ts.map +1 -0
- package/lib/signer/signMessage.js +31 -0
- package/lib/signer/signMessage.js.map +1 -0
- package/lib/test/bot-deviceActions.d.ts +7 -0
- package/lib/test/bot-deviceActions.d.ts.map +1 -0
- package/lib/test/bot-deviceActions.js +23 -0
- package/lib/test/bot-deviceActions.js.map +1 -0
- package/lib/test/bot-specs.d.ts +8 -0
- package/lib/test/bot-specs.d.ts.map +1 -0
- package/lib/test/bot-specs.js +161 -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 +252 -0
- package/lib/test/bridgeDatasetTest.js.map +1 -0
- package/lib/test/cli.d.ts +17 -0
- package/lib/test/cli.d.ts.map +1 -0
- package/lib/test/cli.js +51 -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 +25 -0
- package/lib/types/bridge.d.ts.map +1 -0
- package/lib/types/bridge.js +3 -0
- package/lib/types/bridge.js.map +1 -0
- package/lib/types/constants.d.ts +6 -0
- package/lib/types/constants.d.ts.map +1 -0
- package/lib/types/constants.js +9 -0
- package/lib/types/constants.js.map +1 -0
- package/lib/types/index.d.ts +5 -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/network.d.ts +71 -0
- package/lib/types/network.d.ts.map +1 -0
- package/lib/types/network.js +3 -0
- package/lib/types/network.js.map +1 -0
- package/lib/types/signer.d.ts +12 -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/account.d.ts +7 -0
- package/lib-es/account.d.ts.map +1 -0
- package/lib-es/account.js +17 -0
- package/lib-es/account.js.map +1 -0
- package/lib-es/bridge/broadcast.d.ts +8 -0
- package/lib-es/bridge/broadcast.d.ts.map +1 -0
- package/lib-es/bridge/broadcast.js +23 -0
- package/lib-es/bridge/broadcast.js.map +1 -0
- package/lib-es/bridge/buildOptimisticOperatioin.d.ts +4 -0
- package/lib-es/bridge/buildOptimisticOperatioin.d.ts.map +1 -0
- package/lib-es/bridge/buildOptimisticOperatioin.js +49 -0
- package/lib-es/bridge/buildOptimisticOperatioin.js.map +1 -0
- package/lib-es/bridge/createTransaction.d.ts +9 -0
- package/lib-es/bridge/createTransaction.d.ts.map +1 -0
- package/lib-es/bridge/createTransaction.js +29 -0
- package/lib-es/bridge/createTransaction.js.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.d.ts +4 -0
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.js +22 -0
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -0
- package/lib-es/bridge/getTransactionStatus.d.ts +5 -0
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -0
- package/lib-es/bridge/getTransactionStatus.js +69 -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 +55 -0
- package/lib-es/bridge/index.js.map +1 -0
- package/lib-es/bridge/prepareTransaction.d.ts +10 -0
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -0
- package/lib-es/bridge/prepareTransaction.js +34 -0
- package/lib-es/bridge/prepareTransaction.js.map +1 -0
- package/lib-es/bridge/signOperation.d.ts +8 -0
- package/lib-es/bridge/signOperation.d.ts.map +1 -0
- package/lib-es/bridge/signOperation.js +39 -0
- package/lib-es/bridge/signOperation.js.map +1 -0
- package/lib-es/bridge/synchronisation.d.ts +4 -0
- package/lib-es/bridge/synchronisation.d.ts.map +1 -0
- package/lib-es/bridge/synchronisation.js +77 -0
- package/lib-es/bridge/synchronisation.js.map +1 -0
- package/lib-es/bridge/transaction.d.ts +17 -0
- package/lib-es/bridge/transaction.d.ts.map +1 -0
- package/lib-es/bridge/transaction.js +48 -0
- package/lib-es/bridge/transaction.js.map +1 -0
- package/lib-es/common-logic/address-utils.d.ts +2 -0
- package/lib-es/common-logic/address-utils.d.ts.map +1 -0
- package/lib-es/common-logic/address-utils.js +12 -0
- package/lib-es/common-logic/address-utils.js.map +1 -0
- package/lib-es/common-logic/hex-utils.d.ts +8 -0
- package/lib-es/common-logic/hex-utils.d.ts.map +1 -0
- package/lib-es/common-logic/hex-utils.js +50 -0
- package/lib-es/common-logic/hex-utils.js.map +1 -0
- package/lib-es/common-logic/index.d.ts +7 -0
- package/lib-es/common-logic/index.d.ts.map +1 -0
- package/lib-es/common-logic/index.js +7 -0
- package/lib-es/common-logic/index.js.map +1 -0
- package/lib-es/common-logic/logic.d.ts +5 -0
- package/lib-es/common-logic/logic.d.ts.map +1 -0
- package/lib-es/common-logic/logic.js +38 -0
- package/lib-es/common-logic/logic.js.map +1 -0
- package/lib-es/common-logic/mapping-utils.d.ts +5 -0
- package/lib-es/common-logic/mapping-utils.d.ts.map +1 -0
- package/lib-es/common-logic/mapping-utils.js +53 -0
- package/lib-es/common-logic/mapping-utils.js.map +1 -0
- package/lib-es/common-logic/pad-address.d.ts +2 -0
- package/lib-es/common-logic/pad-address.d.ts.map +1 -0
- package/lib-es/common-logic/pad-address.js +9 -0
- package/lib-es/common-logic/pad-address.js.map +1 -0
- package/lib-es/common-logic/transaction-utils.d.ts +30 -0
- package/lib-es/common-logic/transaction-utils.d.ts.map +1 -0
- package/lib-es/common-logic/transaction-utils.js +153 -0
- package/lib-es/common-logic/transaction-utils.js.map +1 -0
- package/lib-es/config.d.ts +5 -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/contracts/abis/VIP180.d.ts +17 -0
- package/lib-es/contracts/abis/VIP180.d.ts.map +1 -0
- package/lib-es/contracts/abis/VIP180.js +263 -0
- package/lib-es/contracts/abis/VIP180.js.map +1 -0
- package/lib-es/contracts/abis/params.d.ts +8 -0
- package/lib-es/contracts/abis/params.d.ts.map +1 -0
- package/lib-es/contracts/abis/params.js +67 -0
- package/lib-es/contracts/abis/params.js.map +1 -0
- package/lib-es/contracts/constants.d.ts +6 -0
- package/lib-es/contracts/constants.d.ts.map +1 -0
- package/lib-es/contracts/constants.js +7 -0
- package/lib-es/contracts/constants.js.map +1 -0
- package/lib-es/datasets/index.d.ts +3 -0
- package/lib-es/datasets/index.d.ts.map +1 -0
- package/lib-es/datasets/index.js +3 -0
- package/lib-es/datasets/index.js.map +1 -0
- package/lib-es/datasets/vechain.d.ts +5 -0
- package/lib-es/datasets/vechain.d.ts.map +1 -0
- package/lib-es/datasets/vechain.js +88 -0
- package/lib-es/datasets/vechain.js.map +1 -0
- package/lib-es/datasets/vechain.scanAccounts.1.d.ts +6 -0
- package/lib-es/datasets/vechain.scanAccounts.1.d.ts.map +1 -0
- package/lib-es/datasets/vechain.scanAccounts.1.js +14 -0
- package/lib-es/datasets/vechain.scanAccounts.1.js.map +1 -0
- package/lib-es/errors.d.ts +10 -0
- package/lib-es/errors.d.ts.map +1 -0
- package/lib-es/errors.js +5 -0
- package/lib-es/errors.js.map +1 -0
- package/lib-es/index.d.ts +2 -0
- package/lib-es/index.d.ts.map +1 -0
- package/lib-es/index.js +2 -0
- package/lib-es/index.js.map +1 -0
- package/lib-es/mock.d.ts +9 -0
- package/lib-es/mock.d.ts.map +1 -0
- package/lib-es/mock.js +11 -0
- package/lib-es/mock.js.map +1 -0
- package/lib-es/network/index.d.ts +3 -0
- package/lib-es/network/index.d.ts.map +1 -0
- package/lib-es/network/index.js +3 -0
- package/lib-es/network/index.js.map +1 -0
- package/lib-es/network/sdk.d.ts +47 -0
- package/lib-es/network/sdk.d.ts.map +1 -0
- package/lib-es/network/sdk.js +150 -0
- package/lib-es/network/sdk.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 +27 -0
- package/lib-es/signer/getAddress.js.map +1 -0
- package/lib-es/signer/index.d.ts +4 -0
- package/lib-es/signer/index.d.ts.map +1 -0
- package/lib-es/signer/index.js +4 -0
- package/lib-es/signer/index.js.map +1 -0
- package/lib-es/signer/signMessage.d.ts +4 -0
- package/lib-es/signer/signMessage.d.ts.map +1 -0
- package/lib-es/signer/signMessage.js +27 -0
- package/lib-es/signer/signMessage.js.map +1 -0
- package/lib-es/test/bot-deviceActions.d.ts +7 -0
- package/lib-es/test/bot-deviceActions.d.ts.map +1 -0
- package/lib-es/test/bot-deviceActions.js +21 -0
- package/lib-es/test/bot-deviceActions.js.map +1 -0
- package/lib-es/test/bot-specs.d.ts +8 -0
- package/lib-es/test/bot-specs.d.ts.map +1 -0
- package/lib-es/test/bot-specs.js +156 -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 +246 -0
- package/lib-es/test/bridgeDatasetTest.js.map +1 -0
- package/lib-es/test/cli.d.ts +17 -0
- package/lib-es/test/cli.d.ts.map +1 -0
- package/lib-es/test/cli.js +45 -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 +25 -0
- package/lib-es/types/bridge.d.ts.map +1 -0
- package/lib-es/types/bridge.js +2 -0
- package/lib-es/types/bridge.js.map +1 -0
- package/lib-es/types/constants.d.ts +6 -0
- package/lib-es/types/constants.d.ts.map +1 -0
- package/lib-es/types/constants.js +6 -0
- package/lib-es/types/constants.js.map +1 -0
- package/lib-es/types/index.d.ts +5 -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/network.d.ts +71 -0
- package/lib-es/types/network.d.ts.map +1 -0
- package/lib-es/types/network.js +2 -0
- package/lib-es/types/network.js.map +1 -0
- package/lib-es/types/signer.d.ts +12 -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 +120 -0
- package/src/__snapshots__/bridge.integration.test.ts.snap +146 -0
- package/src/account.ts +22 -0
- package/src/bridge/broadcast.ts +23 -0
- package/src/bridge/buildOptimisticOperatioin.ts +46 -0
- package/src/bridge/createTransaction.ts +31 -0
- package/src/bridge/estimateMaxSpendable.ts +18 -0
- package/src/bridge/getTransactionStatus.ts +76 -0
- package/src/bridge/index.ts +63 -0
- package/src/bridge/prepareTransaction.ts +41 -0
- package/src/bridge/signOperation.ts +53 -0
- package/src/bridge/synchronisation.ts +86 -0
- package/src/bridge/transaction.ts +79 -0
- package/src/common-logic/address-utils.ts +11 -0
- package/src/common-logic/hex-utils.ts +53 -0
- package/src/common-logic/index.ts +6 -0
- package/src/common-logic/logic.ts +44 -0
- package/src/common-logic/mapping-utils.ts +67 -0
- package/src/common-logic/pad-address.ts +8 -0
- package/src/common-logic/transaction-utils.ts +190 -0
- package/src/config.ts +18 -0
- package/src/contracts/abis/VIP180.ts +265 -0
- package/src/contracts/abis/params.ts +70 -0
- package/src/contracts/constants.ts +11 -0
- package/src/datasets/index.ts +2 -0
- package/src/datasets/vechain.scanAccounts.1.ts +13 -0
- package/src/datasets/vechain.ts +92 -0
- package/src/errors.ts +7 -0
- package/src/index.ts +1 -0
- package/src/mock.ts +14 -0
- package/src/network/index.ts +2 -0
- package/src/network/sdk.ts +177 -0
- package/src/signer/getAddress.ts +25 -0
- package/src/signer/index.ts +4 -0
- package/src/signer/signMessage.ts +22 -0
- package/src/test/bot-deviceActions.ts +24 -0
- package/src/test/bot-specs.ts +210 -0
- package/src/test/bridgeDatasetTest.ts +262 -0
- package/src/test/cli.ts +86 -0
- package/src/test/index.ts +6 -0
- package/src/types/bridge.ts +35 -0
- package/src/types/constants.ts +5 -0
- package/src/types/index.ts +4 -0
- package/src/types/network.ts +81 -0
- package/src/types/signer.ts +10 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Account } from "@ledgerhq/types-live";
|
|
2
|
+
import { Transaction as VeChainThorTransaction } from "thor-devkit";
|
|
3
|
+
import {
|
|
4
|
+
calculateTransactionInfo,
|
|
5
|
+
isValid,
|
|
6
|
+
calculateClausesVet,
|
|
7
|
+
calculateClausesVtho,
|
|
8
|
+
} from "../common-logic";
|
|
9
|
+
import { Transaction } from "../types";
|
|
10
|
+
import { getBlockRef } from "../network";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Prepare transaction before checking status
|
|
14
|
+
*
|
|
15
|
+
* @param {Account} a
|
|
16
|
+
* @param {Transaction} t
|
|
17
|
+
*/
|
|
18
|
+
export const prepareTransaction = async (
|
|
19
|
+
account: Account,
|
|
20
|
+
transaction: Transaction,
|
|
21
|
+
): Promise<Transaction> => {
|
|
22
|
+
const { amount, isTokenAccount, estimatedFees, estimatedGas } = await calculateTransactionInfo(
|
|
23
|
+
account,
|
|
24
|
+
transaction,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
let blockRef = "";
|
|
28
|
+
|
|
29
|
+
let clauses: Array<VeChainThorTransaction.Clause> = [];
|
|
30
|
+
if (transaction.recipient && isValid(transaction.recipient)) {
|
|
31
|
+
blockRef = await getBlockRef();
|
|
32
|
+
if (isTokenAccount) {
|
|
33
|
+
clauses = await calculateClausesVtho(transaction.recipient, amount);
|
|
34
|
+
} else {
|
|
35
|
+
clauses = await calculateClausesVet(transaction.recipient, amount);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const body = { ...transaction.body, gas: estimatedGas, blockRef, clauses };
|
|
40
|
+
return { ...transaction, body, amount, estimatedFees };
|
|
41
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { Transaction as ThorTransaction } from "thor-devkit";
|
|
3
|
+
import type { Account, AccountBridge, DeviceId, SignOperationEvent } from "@ledgerhq/types-live";
|
|
4
|
+
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
5
|
+
import { buildOptimisticOperation } from "./buildOptimisticOperatioin";
|
|
6
|
+
import type { Transaction, VechainSigner } from "../types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sign Transaction with Ledger hardware
|
|
10
|
+
*/
|
|
11
|
+
export const buildSignOperation =
|
|
12
|
+
(signerContext: SignerContext<VechainSigner>): AccountBridge<Transaction>["signOperation"] =>
|
|
13
|
+
({
|
|
14
|
+
account,
|
|
15
|
+
transaction,
|
|
16
|
+
deviceId,
|
|
17
|
+
}: {
|
|
18
|
+
account: Account;
|
|
19
|
+
transaction: Transaction;
|
|
20
|
+
deviceId: DeviceId;
|
|
21
|
+
}): Observable<SignOperationEvent> =>
|
|
22
|
+
new Observable(o => {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
24
|
+
async function main() {
|
|
25
|
+
const unsigned = new ThorTransaction(transaction.body);
|
|
26
|
+
|
|
27
|
+
o.next({
|
|
28
|
+
type: "device-signature-requested",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const signature = await signerContext(deviceId, signer =>
|
|
32
|
+
signer.signTransaction(account.freshAddressPath, unsigned.encode().toString("hex")),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
o.next({ type: "device-signature-granted" });
|
|
36
|
+
|
|
37
|
+
const operation = await buildOptimisticOperation(account, transaction);
|
|
38
|
+
|
|
39
|
+
o.next({
|
|
40
|
+
type: "signed",
|
|
41
|
+
signedOperation: {
|
|
42
|
+
operation,
|
|
43
|
+
signature: signature.toString("hex"),
|
|
44
|
+
rawData: transaction,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
main().then(
|
|
50
|
+
() => o.complete(),
|
|
51
|
+
e => o.error(e),
|
|
52
|
+
);
|
|
53
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { BigNumber } from "bignumber.js";
|
|
2
|
+
|
|
3
|
+
import eip55 from "eip55";
|
|
4
|
+
import {
|
|
5
|
+
emptyHistoryCache,
|
|
6
|
+
encodeAccountId,
|
|
7
|
+
encodeTokenAccountId,
|
|
8
|
+
} from "@ledgerhq/coin-framework/account/index";
|
|
9
|
+
|
|
10
|
+
import { getAccount, getLastBlockHeight, getOperations, getTokenOperations } from "../network";
|
|
11
|
+
import { findTokenById, getTokenById } from "@ledgerhq/cryptoassets/tokens";
|
|
12
|
+
import { VTHO_ADDRESS } from "../contracts/constants";
|
|
13
|
+
import { GetAccountShape, mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
14
|
+
import { Account } from "@ledgerhq/types-live";
|
|
15
|
+
|
|
16
|
+
export const getAccountShape: GetAccountShape<Account> = async info => {
|
|
17
|
+
const { initialAccount, currency, derivationMode } = info;
|
|
18
|
+
const address = eip55.encode(info.address);
|
|
19
|
+
|
|
20
|
+
const oldOperations = initialAccount?.operations || [];
|
|
21
|
+
const startAt = oldOperations.length ? (oldOperations[0].blockHeight || 0) + 1 : 1;
|
|
22
|
+
|
|
23
|
+
const accountId = encodeAccountId({
|
|
24
|
+
type: "js",
|
|
25
|
+
version: "2",
|
|
26
|
+
currencyId: currency.id,
|
|
27
|
+
xpubOrAddress: address,
|
|
28
|
+
derivationMode,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// get the current account balance state depending your api implementation
|
|
32
|
+
const { balance, energy } = await getAccount(address);
|
|
33
|
+
|
|
34
|
+
// get the current block height
|
|
35
|
+
const blockHeight = await getLastBlockHeight();
|
|
36
|
+
|
|
37
|
+
// Merge new operations with the previously synced ones
|
|
38
|
+
const newOperations = await getOperations(accountId, address, startAt);
|
|
39
|
+
|
|
40
|
+
//Get last token operations
|
|
41
|
+
const vthoAccountId = encodeTokenAccountId(accountId, findTokenById("vechain/vip180/vtho")!);
|
|
42
|
+
const vthoOperations = await getTokenOperations(vthoAccountId, address, VTHO_ADDRESS, 1); // from parameter must be 1 otherwise the response is empty
|
|
43
|
+
|
|
44
|
+
const operations = mergeOps(oldOperations, newOperations);
|
|
45
|
+
|
|
46
|
+
//Account creation date set to now if there are no operation or at the first operation on the account
|
|
47
|
+
let minDate = -1;
|
|
48
|
+
if (operations.length != 0) {
|
|
49
|
+
const operationsDates = operations.map(c => c.date.getTime());
|
|
50
|
+
operationsDates.concat(vthoOperations.map(c => c.date.getTime()));
|
|
51
|
+
minDate = Math.min(...operationsDates);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const shape = {
|
|
55
|
+
id: accountId,
|
|
56
|
+
balance: new BigNumber(balance),
|
|
57
|
+
creationDate: minDate != -1 ? new Date(minDate) : new Date(),
|
|
58
|
+
spendableBalance: new BigNumber(balance),
|
|
59
|
+
operationsCount: operations.length,
|
|
60
|
+
operations,
|
|
61
|
+
blockHeight,
|
|
62
|
+
feesCurrency: getTokenById("vechain/vip180/vtho"),
|
|
63
|
+
subAccounts: [
|
|
64
|
+
{
|
|
65
|
+
type: "TokenAccount" as const,
|
|
66
|
+
id: vthoAccountId,
|
|
67
|
+
parentId: accountId,
|
|
68
|
+
token: getTokenById("vechain/vip180/vtho"),
|
|
69
|
+
balance: new BigNumber(energy),
|
|
70
|
+
spendableBalance: new BigNumber(energy),
|
|
71
|
+
creationDate: minDate != -1 ? new Date(minDate) : new Date(),
|
|
72
|
+
operationsCount: vthoOperations.length,
|
|
73
|
+
operations: vthoOperations,
|
|
74
|
+
blockHeight,
|
|
75
|
+
pendingOperations:
|
|
76
|
+
(initialAccount?.subAccounts && initialAccount.subAccounts[0]?.pendingOperations) || [],
|
|
77
|
+
balanceHistoryCache:
|
|
78
|
+
(initialAccount?.subAccounts && initialAccount.subAccounts[0]?.balanceHistoryCache) ||
|
|
79
|
+
emptyHistoryCache,
|
|
80
|
+
swapHistory: [],
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return shape;
|
|
86
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getAccountCurrency } from "@ledgerhq/coin-framework/account/index";
|
|
2
|
+
import type {
|
|
3
|
+
Transaction,
|
|
4
|
+
TransactionRaw,
|
|
5
|
+
TransactionStatus,
|
|
6
|
+
TransactionStatusRaw,
|
|
7
|
+
} from "../types";
|
|
8
|
+
import { formatTransactionStatus } from "@ledgerhq/coin-framework/formatters";
|
|
9
|
+
import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/index";
|
|
10
|
+
import {
|
|
11
|
+
fromTransactionCommonRaw,
|
|
12
|
+
fromTransactionStatusRawCommon,
|
|
13
|
+
toTransactionCommonRaw,
|
|
14
|
+
toTransactionStatusRawCommon,
|
|
15
|
+
} from "@ledgerhq/coin-framework/serialization";
|
|
16
|
+
import type { Account } from "@ledgerhq/types-live";
|
|
17
|
+
|
|
18
|
+
export const formatTransaction = (t: Transaction, account: Account): string => {
|
|
19
|
+
const { amount, recipient, useAllAmount } = t;
|
|
20
|
+
let displayedAmount: string;
|
|
21
|
+
if (useAllAmount) {
|
|
22
|
+
displayedAmount = "MAX";
|
|
23
|
+
} else if (amount.isZero()) {
|
|
24
|
+
displayedAmount = "";
|
|
25
|
+
} else {
|
|
26
|
+
displayedAmount =
|
|
27
|
+
" " +
|
|
28
|
+
formatCurrencyUnit(getAccountCurrency(account).units[0], amount, {
|
|
29
|
+
showCode: true,
|
|
30
|
+
disableRounding: true,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return `SEND ${displayedAmount} TO ${recipient}`;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const fromTransactionRaw = (tr: TransactionRaw): Transaction => {
|
|
37
|
+
const common = fromTransactionCommonRaw(tr);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
...tr,
|
|
41
|
+
...common,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const toTransactionRaw = (t: Transaction): TransactionRaw => {
|
|
46
|
+
const common = toTransactionCommonRaw(t);
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
...t,
|
|
50
|
+
...common,
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const fromTransactionStatusRaw = (ts: TransactionStatusRaw): TransactionStatus => {
|
|
55
|
+
const common = fromTransactionStatusRawCommon(ts);
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
...ts,
|
|
59
|
+
...common,
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const toTransactionStatusRaw = (ts: TransactionStatus): TransactionStatusRaw => {
|
|
64
|
+
const common = toTransactionStatusRawCommon(ts);
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
...ts,
|
|
68
|
+
...common,
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default {
|
|
73
|
+
formatTransaction,
|
|
74
|
+
formatTransactionStatus,
|
|
75
|
+
fromTransactionRaw,
|
|
76
|
+
toTransactionRaw,
|
|
77
|
+
fromTransactionStatusRaw,
|
|
78
|
+
toTransactionStatusRaw,
|
|
79
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const PREFIX = "0x";
|
|
2
|
+
const PREFIX_REGEX = /^0[xX]/;
|
|
3
|
+
const HEX_REGEX = /^(0[xX])?[a-fA-F0-9]+$/;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the provied hex string with the hex prefix removed.
|
|
7
|
+
* If the prefix doesn't exist the hex is returned unmodified
|
|
8
|
+
* @param hex - the input hex string
|
|
9
|
+
* @returns the input hex string with the hex prefix removed
|
|
10
|
+
* @throws an error if the input is not a valid hex string
|
|
11
|
+
*/
|
|
12
|
+
const removePrefix = (hex: string): string => {
|
|
13
|
+
validate(hex);
|
|
14
|
+
return hex.replace(PREFIX_REGEX, "");
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Returns the provided hex string with the hex prefix added.
|
|
19
|
+
* If the prefix already exists the string is returned unmodified.
|
|
20
|
+
* If the string contains an UPPER case `X` in the prefix it will be replaced with a lower case `x`
|
|
21
|
+
* @param hex - the input hex string
|
|
22
|
+
* @returns the input hex string with the hex prefix added
|
|
23
|
+
* @throws an error if the input is not a valid hex string
|
|
24
|
+
*/
|
|
25
|
+
const addPrefix = (hex: string): string => {
|
|
26
|
+
validate(hex);
|
|
27
|
+
return PREFIX_REGEX.test(hex) ? hex.replace(PREFIX_REGEX, PREFIX) : `${PREFIX}${hex}`;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Validate the hex string. Throws an Error if not valid
|
|
32
|
+
* @param hex - the input hex string
|
|
33
|
+
* @throws an error if the input is not a valid hex string
|
|
34
|
+
*/
|
|
35
|
+
const validate = (hex: string) => {
|
|
36
|
+
if (!isValid(hex)) throw Error(`Provided hex value is not valid ${hex}`);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check if input string is valid
|
|
41
|
+
* @param hex - the input hex string
|
|
42
|
+
* @returns boolean representing whether the input hex is valid
|
|
43
|
+
*/
|
|
44
|
+
const isValid = (hex: string): boolean => {
|
|
45
|
+
return HEX_REGEX.test(hex);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
removePrefix,
|
|
50
|
+
addPrefix,
|
|
51
|
+
validate,
|
|
52
|
+
isValid,
|
|
53
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { Transaction as VeChainThorTransaction } from "thor-devkit";
|
|
3
|
+
import { VTHO_ADDRESS } from "../contracts/constants";
|
|
4
|
+
import VIP180 from "../contracts/abis/VIP180";
|
|
5
|
+
import { HEX_PREFIX } from "../types";
|
|
6
|
+
|
|
7
|
+
export const calculateClausesVtho = async (
|
|
8
|
+
recipient: string,
|
|
9
|
+
amount: BigNumber,
|
|
10
|
+
): Promise<VeChainThorTransaction.Clause[]> => {
|
|
11
|
+
const clauses: VeChainThorTransaction.Clause[] = [];
|
|
12
|
+
|
|
13
|
+
// Get the existing clause or create a blank one
|
|
14
|
+
const updatedClause: VeChainThorTransaction.Clause = {
|
|
15
|
+
to: VTHO_ADDRESS,
|
|
16
|
+
value: 0,
|
|
17
|
+
data: "0x",
|
|
18
|
+
};
|
|
19
|
+
updatedClause.data = VIP180.transfer.encode(recipient, amount.toFixed());
|
|
20
|
+
|
|
21
|
+
clauses.push(updatedClause);
|
|
22
|
+
return clauses;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const calculateClausesVet = async (
|
|
26
|
+
recipient: string,
|
|
27
|
+
amount: BigNumber,
|
|
28
|
+
): Promise<VeChainThorTransaction.Clause[]> => {
|
|
29
|
+
const clauses: VeChainThorTransaction.Clause[] = [];
|
|
30
|
+
|
|
31
|
+
// Get the existing clause or create a blank one
|
|
32
|
+
const updatedClause: VeChainThorTransaction.Clause = {
|
|
33
|
+
to: null,
|
|
34
|
+
value: 0,
|
|
35
|
+
data: "0x",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
updatedClause.value = `${HEX_PREFIX}${amount.toString(16)}`;
|
|
39
|
+
updatedClause.to = recipient;
|
|
40
|
+
|
|
41
|
+
clauses.push(updatedClause);
|
|
42
|
+
|
|
43
|
+
return clauses;
|
|
44
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import vip180 from "../contracts/abis/VIP180";
|
|
3
|
+
import { Operation } from "@ledgerhq/types-live";
|
|
4
|
+
import { EventLog, TransferLog } from "../types";
|
|
5
|
+
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
6
|
+
import { getFees } from "../network";
|
|
7
|
+
|
|
8
|
+
export const mapVetTransfersToOperations = async (
|
|
9
|
+
txs: TransferLog[],
|
|
10
|
+
accountId: string,
|
|
11
|
+
addr: string,
|
|
12
|
+
): Promise<Operation[]> => {
|
|
13
|
+
return Promise.all(
|
|
14
|
+
txs.map(async tx => {
|
|
15
|
+
const fees = await getFees(tx.meta.txID);
|
|
16
|
+
return {
|
|
17
|
+
id: encodeOperationId(
|
|
18
|
+
accountId,
|
|
19
|
+
tx.meta.txID,
|
|
20
|
+
tx.recipient === addr.toLowerCase() ? "IN" : "OUT",
|
|
21
|
+
),
|
|
22
|
+
hash: tx.meta.txID,
|
|
23
|
+
type: tx.recipient === addr.toLowerCase() ? "IN" : "OUT",
|
|
24
|
+
value: new BigNumber(tx.amount),
|
|
25
|
+
fee: new BigNumber(fees),
|
|
26
|
+
senders: [tx.sender],
|
|
27
|
+
recipients: [tx.recipient],
|
|
28
|
+
blockHeight: tx.meta.blockNumber,
|
|
29
|
+
blockHash: tx.meta.blockID,
|
|
30
|
+
accountId,
|
|
31
|
+
date: new Date(tx.meta.blockTimestamp * 1000),
|
|
32
|
+
extra: {},
|
|
33
|
+
};
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const mapTokenTransfersToOperations = async (
|
|
39
|
+
evnts: EventLog[],
|
|
40
|
+
accountId: string,
|
|
41
|
+
addr: string,
|
|
42
|
+
): Promise<Operation[]> => {
|
|
43
|
+
return Promise.all(
|
|
44
|
+
evnts.map(async evnt => {
|
|
45
|
+
const decoded = vip180.TransferEvent.decode(evnt.data, evnt.topics);
|
|
46
|
+
const fees = await getFees(evnt.meta.txID);
|
|
47
|
+
return {
|
|
48
|
+
id: encodeOperationId(
|
|
49
|
+
accountId,
|
|
50
|
+
evnt.meta.txID,
|
|
51
|
+
decoded.to === addr.toLowerCase() ? "IN" : "OUT",
|
|
52
|
+
),
|
|
53
|
+
hash: evnt.meta.txID,
|
|
54
|
+
type: decoded.to === addr.toLowerCase() ? "IN" : "OUT",
|
|
55
|
+
value: new BigNumber(decoded.value),
|
|
56
|
+
fee: fees,
|
|
57
|
+
senders: [decoded.from],
|
|
58
|
+
recipients: [decoded.to],
|
|
59
|
+
blockHeight: evnt.meta.blockNumber,
|
|
60
|
+
blockHash: evnt.meta.blockID,
|
|
61
|
+
accountId,
|
|
62
|
+
date: new Date(evnt.meta.blockTimestamp * 1000),
|
|
63
|
+
extra: {},
|
|
64
|
+
};
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const padAddress = (address: string): string => {
|
|
2
|
+
const splittedAddr = address.split("x");
|
|
3
|
+
const hexMiss = 64 - splittedAddr[1].length;
|
|
4
|
+
for (let i = 0; i < hexMiss; i++) {
|
|
5
|
+
splittedAddr[1] = `0${splittedAddr[1]}`;
|
|
6
|
+
}
|
|
7
|
+
return splittedAddr.join("x");
|
|
8
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { DEFAULT_GAS_COEFFICIENT, HEX_PREFIX } from "../types";
|
|
3
|
+
import crypto from "crypto";
|
|
4
|
+
import { Transaction as ThorTransaction } from "thor-devkit";
|
|
5
|
+
import params from "../contracts/abis/params";
|
|
6
|
+
import { BASE_GAS_PRICE_KEY, PARAMS_ADDRESS } from "../contracts/constants";
|
|
7
|
+
import { query } from "../network";
|
|
8
|
+
import { Account, TokenAccount } from "@ledgerhq/types-live";
|
|
9
|
+
import { Transaction, TransactionInfo, Query } from "../types";
|
|
10
|
+
import { isValid } from "./address-utils";
|
|
11
|
+
import { calculateClausesVet, calculateClausesVtho } from "./logic";
|
|
12
|
+
import { ImpossibleToCalculateAmountAndFees } from "../errors";
|
|
13
|
+
|
|
14
|
+
const GAS_COEFFICIENT = 15000;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Generate a Unique ID to be used as a nonce
|
|
18
|
+
* @returns a unique string
|
|
19
|
+
*/
|
|
20
|
+
export const generateNonce = (): string => {
|
|
21
|
+
const randBuffer = crypto.randomBytes(Math.ceil(4));
|
|
22
|
+
if (!randBuffer) throw Error("Failed to generate random hex");
|
|
23
|
+
return `${HEX_PREFIX}${randBuffer.toString("hex").substring(0, 8)}`;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Estimate the gas that will be used by the transaction.
|
|
28
|
+
* @param transaction - The transaction to estimate the gas for
|
|
29
|
+
* @returns an estimate of the gas usage
|
|
30
|
+
*/
|
|
31
|
+
export const estimateGas = async (t: Transaction): Promise<number> => {
|
|
32
|
+
const intrinsicGas = ThorTransaction.intrinsicGas(t.body.clauses);
|
|
33
|
+
|
|
34
|
+
const queryData: Query[] = [];
|
|
35
|
+
|
|
36
|
+
t.body.clauses.forEach(c => {
|
|
37
|
+
if (c.to) {
|
|
38
|
+
queryData.push({
|
|
39
|
+
to: c.to,
|
|
40
|
+
data: c.data,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const response = await query(queryData);
|
|
46
|
+
|
|
47
|
+
const execGas = response.reduce((sum, out) => sum + out.gasUsed, 0);
|
|
48
|
+
|
|
49
|
+
return intrinsicGas + (execGas ? execGas + GAS_COEFFICIENT : 0);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const getBaseGasPrice = async (): Promise<string> => {
|
|
53
|
+
const queryData: Query = {
|
|
54
|
+
to: PARAMS_ADDRESS,
|
|
55
|
+
data: params.get.encode(BASE_GAS_PRICE_KEY),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const response = await query([queryData]);
|
|
59
|
+
|
|
60
|
+
// Expect 1 value
|
|
61
|
+
if (response && response.length != 1) throw Error("Unexpected response received for query");
|
|
62
|
+
|
|
63
|
+
return response[0].data;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Calculate the fee in VTHO
|
|
68
|
+
* @param gas - the gas used
|
|
69
|
+
* @param gasPriceCoef - the gas price coefficient
|
|
70
|
+
* @returns the fee in VTHO
|
|
71
|
+
*/
|
|
72
|
+
export const calculateFee = async (gas: BigNumber, gasPriceCoef: number): Promise<BigNumber> => {
|
|
73
|
+
const baseGasPrice = await getBaseGasPrice();
|
|
74
|
+
return new BigNumber(baseGasPrice).times(gasPriceCoef).idiv(255).plus(baseGasPrice).times(gas);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Here there is a circular dependency between values, that is why we need the do-while loop
|
|
78
|
+
// dependencies are:
|
|
79
|
+
// useAllAmount: USER
|
|
80
|
+
// amount: useAllAmount & spendableBalance
|
|
81
|
+
// fees: amount
|
|
82
|
+
// spendableBalance: fees & balance
|
|
83
|
+
// balance: USER
|
|
84
|
+
// circular dependency is:
|
|
85
|
+
// amount -> spendableBalance -> fees -> amount
|
|
86
|
+
|
|
87
|
+
export const calculateTransactionInfo = async (
|
|
88
|
+
account: Account,
|
|
89
|
+
transaction: Transaction,
|
|
90
|
+
fixedMaxTokenFees?: {
|
|
91
|
+
estimatedGas: number;
|
|
92
|
+
estimatedGasFees: BigNumber;
|
|
93
|
+
},
|
|
94
|
+
): Promise<TransactionInfo> => {
|
|
95
|
+
const { subAccounts } = account;
|
|
96
|
+
const { amount: oldAmount, subAccountId, useAllAmount } = transaction;
|
|
97
|
+
|
|
98
|
+
const tokenAccount =
|
|
99
|
+
subAccountId && subAccounts
|
|
100
|
+
? (subAccounts.find(subAccount => {
|
|
101
|
+
return subAccount.id === subAccountId;
|
|
102
|
+
}) as TokenAccount)
|
|
103
|
+
: undefined;
|
|
104
|
+
const isTokenAccount = !!tokenAccount;
|
|
105
|
+
|
|
106
|
+
let amount = oldAmount;
|
|
107
|
+
let amountBackup;
|
|
108
|
+
let tempTransaction = { ...transaction, amount };
|
|
109
|
+
let balance = account.balance;
|
|
110
|
+
let spendableBalance = account.balance;
|
|
111
|
+
let maxEstimatedGasFees = new BigNumber(0);
|
|
112
|
+
let maxEstimatedGas = 0;
|
|
113
|
+
|
|
114
|
+
if (!amount.isNaN()) {
|
|
115
|
+
const MAX_ITERATIONS = 5; // it should never reach more than 2 iterations, but just in case
|
|
116
|
+
let iterations = 0;
|
|
117
|
+
do {
|
|
118
|
+
amountBackup = amount;
|
|
119
|
+
|
|
120
|
+
const estimatedGasAndFees =
|
|
121
|
+
fixedMaxTokenFees || (await calculateGasFees(tempTransaction, isTokenAccount));
|
|
122
|
+
|
|
123
|
+
maxEstimatedGasFees = estimatedGasAndFees.estimatedGasFees;
|
|
124
|
+
maxEstimatedGas = estimatedGasAndFees.estimatedGas;
|
|
125
|
+
|
|
126
|
+
if (isTokenAccount && tokenAccount) {
|
|
127
|
+
balance = tokenAccount.balance;
|
|
128
|
+
spendableBalance = tokenAccount.balance.minus(maxEstimatedGasFees).gt(0)
|
|
129
|
+
? tokenAccount.balance.minus(maxEstimatedGasFees)
|
|
130
|
+
: new BigNumber(0);
|
|
131
|
+
} else {
|
|
132
|
+
balance = account.balance;
|
|
133
|
+
spendableBalance = account.balance;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
amount = useAllAmount ? spendableBalance : oldAmount;
|
|
137
|
+
|
|
138
|
+
tempTransaction = {
|
|
139
|
+
...tempTransaction,
|
|
140
|
+
amount,
|
|
141
|
+
};
|
|
142
|
+
iterations++;
|
|
143
|
+
} while (!amountBackup.isEqualTo(amount) && iterations < MAX_ITERATIONS);
|
|
144
|
+
if (iterations === MAX_ITERATIONS) {
|
|
145
|
+
throw new ImpossibleToCalculateAmountAndFees();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
isTokenAccount,
|
|
151
|
+
amount,
|
|
152
|
+
spendableBalance,
|
|
153
|
+
balance,
|
|
154
|
+
tokenAccount,
|
|
155
|
+
estimatedFees: maxEstimatedGasFees.toString(),
|
|
156
|
+
estimatedGas: maxEstimatedGas,
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export const calculateGasFees = async (
|
|
161
|
+
transaction: Transaction,
|
|
162
|
+
isTokenAccount: boolean,
|
|
163
|
+
): Promise<{
|
|
164
|
+
estimatedGas: number;
|
|
165
|
+
estimatedGasFees: BigNumber;
|
|
166
|
+
}> => {
|
|
167
|
+
if (transaction.recipient && isValid(transaction.recipient)) {
|
|
168
|
+
let clauses;
|
|
169
|
+
if (isTokenAccount) {
|
|
170
|
+
clauses = await calculateClausesVtho(transaction.recipient, transaction.amount);
|
|
171
|
+
} else {
|
|
172
|
+
clauses = await calculateClausesVet(transaction.recipient, transaction.amount);
|
|
173
|
+
}
|
|
174
|
+
const gas = await estimateGas({
|
|
175
|
+
...transaction,
|
|
176
|
+
body: { ...transaction.body, clauses: clauses },
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
estimatedGas: gas,
|
|
180
|
+
estimatedGasFees: await calculateFee(
|
|
181
|
+
new BigNumber(gas),
|
|
182
|
+
transaction.body.gasPriceCoef || DEFAULT_GAS_COEFFICIENT,
|
|
183
|
+
),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
estimatedGas: 0,
|
|
188
|
+
estimatedGasFees: new BigNumber(0),
|
|
189
|
+
};
|
|
190
|
+
};
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CurrencyConfig, CoinConfig } from "@ledgerhq/coin-framework/config";
|
|
2
|
+
import { MissingCoinConfig } from "@ledgerhq/coin-framework/errors";
|
|
3
|
+
|
|
4
|
+
export type VechainCoinConfig = () => CurrencyConfig;
|
|
5
|
+
|
|
6
|
+
let coinConfig: CoinConfig<CurrencyConfig> | undefined;
|
|
7
|
+
|
|
8
|
+
export function setCoinConfig(config: CoinConfig<CurrencyConfig>): void {
|
|
9
|
+
coinConfig = config;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getCoinConfig(): CurrencyConfig {
|
|
13
|
+
if (!coinConfig) {
|
|
14
|
+
throw new MissingCoinConfig();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return coinConfig();
|
|
18
|
+
}
|