@ledgerhq/live-common 27.3.2 → 27.4.0-next.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/lib/__tests__/environment.test.d.ts +2 -0
- package/lib/__tests__/environment.test.d.ts.map +1 -0
- package/lib/__tests__/environment.test.js +13 -0
- package/lib/__tests__/environment.test.js.map +1 -0
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.syncing.integration.test.js +0 -31
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.syncing.integration.test.js.map +1 -1
- package/lib/account/support.d.ts.map +1 -1
- package/lib/account/support.js +3 -2
- package/lib/account/support.js.map +1 -1
- package/lib/apps/hw.d.ts +4 -1
- package/lib/apps/hw.d.ts.map +1 -1
- package/lib/apps/hw.js +10 -4
- package/lib/apps/hw.js.map +1 -1
- package/lib/apps/mock.d.ts +1 -0
- package/lib/apps/mock.d.ts.map +1 -1
- package/lib/apps/mock.js +24 -2
- package/lib/apps/mock.js.map +1 -1
- package/lib/apps/runner.d.ts +8 -1
- package/lib/apps/runner.d.ts.map +1 -1
- package/lib/apps/runner.js +15 -3
- package/lib/apps/runner.js.map +1 -1
- package/lib/apps/support.js +1 -1
- package/lib/bot/engine.d.ts.map +1 -1
- package/lib/bot/engine.js +5 -2
- package/lib/bot/engine.js.map +1 -1
- package/lib/bot/index.d.ts.map +1 -1
- package/lib/bot/index.js +5 -3
- package/lib/bot/index.js.map +1 -1
- package/lib/bot/types.d.ts +2 -0
- package/lib/bot/types.d.ts.map +1 -1
- package/lib/data/icons/react/index.d.ts +1 -0
- package/lib/data/icons/react/index.d.ts.map +1 -1
- package/lib/data/icons/react/index.js +3 -1
- package/lib/data/icons/react/index.js.map +1 -1
- package/lib/data/icons/react/yae.d.ts +8 -0
- package/lib/data/icons/react/yae.d.ts.map +1 -0
- package/lib/data/icons/react/yae.js +36 -0
- package/lib/data/icons/react/yae.js.map +1 -0
- package/lib/data/icons/reactNative/index.d.ts +1 -0
- package/lib/data/icons/reactNative/index.d.ts.map +1 -1
- package/lib/data/icons/reactNative/index.js +3 -1
- package/lib/data/icons/reactNative/index.js.map +1 -1
- package/lib/data/icons/reactNative/yae.d.ts +8 -0
- package/lib/data/icons/reactNative/yae.d.ts.map +1 -0
- package/lib/data/icons/reactNative/yae.js +37 -0
- package/lib/data/icons/reactNative/yae.js.map +1 -0
- package/lib/exchange/hw-app-exchange/Exchange.js +4 -4
- package/lib/families/bitcoin/account.d.ts.map +1 -1
- package/lib/families/bitcoin/bech32m.d.ts +2 -8
- package/lib/families/bitcoin/bech32m.d.ts.map +1 -1
- package/lib/families/bitcoin/bridge/js.d.ts.map +1 -1
- package/lib/families/bitcoin/bridge/js.js.map +1 -1
- package/lib/families/bitcoin/bridge/mock.d.ts.map +1 -1
- package/lib/families/bitcoin/bridge/mock.js.map +1 -1
- package/lib/families/bitcoin/cache.d.ts +2 -15
- package/lib/families/bitcoin/cache.d.ts.map +1 -1
- package/lib/families/bitcoin/js-getFeesForTransaction.d.ts +2 -15
- package/lib/families/bitcoin/js-getFeesForTransaction.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.js.map +1 -1
- package/lib/families/bitcoin/logic.d.ts +1 -1
- package/lib/families/bitcoin/logic.d.ts.map +1 -1
- package/lib/families/bitcoin/logic.js.map +1 -1
- package/lib/families/bitcoin/presync.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/base.d.ts +0 -2
- package/lib/families/bitcoin/wallet-btc/crypto/base.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/base.js +0 -16
- package/lib/families/bitcoin/wallet-btc/crypto/base.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.d.ts +4 -3
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.js +3 -1
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.d.ts +2 -3
- package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.js +0 -7
- package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/factory.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/factory.js +0 -3
- package/lib/families/bitcoin/wallet-btc/crypto/factory.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/litecoin.d.ts +2 -3
- package/lib/families/bitcoin/wallet-btc/crypto/litecoin.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/litecoin.js +0 -16
- package/lib/families/bitcoin/wallet-btc/crypto/litecoin.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/types.d.ts +0 -1
- package/lib/families/bitcoin/wallet-btc/crypto/types.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/zec.d.ts +0 -2
- package/lib/families/bitcoin/wallet-btc/crypto/zec.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/zec.js +0 -5
- package/lib/families/bitcoin/wallet-btc/crypto/zec.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/zen.d.ts +0 -2
- package/lib/families/bitcoin/wallet-btc/crypto/zen.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/zen.js +0 -5
- package/lib/families/bitcoin/wallet-btc/crypto/zen.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/explorer/index.d.ts +11 -5
- package/lib/families/bitcoin/wallet-btc/explorer/index.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/explorer/index.js +8 -40
- package/lib/families/bitcoin/wallet-btc/explorer/index.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.d.ts +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.d.ts +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.d.ts +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/index.d.ts +1 -5
- package/lib/families/bitcoin/wallet-btc/storage/index.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/index.js +7 -9
- package/lib/families/bitcoin/wallet-btc/storage/index.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/utils.d.ts +3 -3
- package/lib/families/bitcoin/wallet-btc/utils.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/utils.js +2 -11
- package/lib/families/bitcoin/wallet-btc/utils.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/wallet.d.ts +10 -7
- package/lib/families/bitcoin/wallet-btc/wallet.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/wallet.js +1 -18
- package/lib/families/bitcoin/wallet-btc/wallet.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/xpub.d.ts +1 -9
- package/lib/families/bitcoin/wallet-btc/xpub.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/xpub.js +60 -208
- package/lib/families/bitcoin/wallet-btc/xpub.js.map +1 -1
- package/lib/families/cardano/js-synchronisation.js +1 -1
- package/lib/families/cardano/js-synchronisation.js.map +1 -1
- package/lib/families/cardano/specs.js +1 -1
- package/lib/families/celo/specs/createSendMutation.d.ts.map +1 -1
- package/lib/families/celo/specs/createSendMutation.js +0 -2
- package/lib/families/celo/specs/createSendMutation.js.map +1 -1
- package/lib/families/celo/specs.js +1 -1
- package/lib/families/crypto_org/specs.d.ts.map +1 -1
- package/lib/families/crypto_org/specs.js +3 -2
- package/lib/families/crypto_org/specs.js.map +1 -1
- package/lib/families/ethereum/specs.js +3 -3
- package/lib/families/ethereum/specs.js.map +1 -1
- package/lib/families/evm/specs.js +6 -6
- package/lib/families/evm/specs.js.map +1 -1
- package/lib/families/filecoin/specs.d.ts.map +1 -1
- package/lib/families/filecoin/specs.js +1 -2
- package/lib/families/filecoin/specs.js.map +1 -1
- package/lib/families/hedera/api/network.d.ts.map +1 -1
- package/lib/families/hedera/api/network.js +16 -8
- package/lib/families/hedera/api/network.js.map +1 -1
- package/lib/families/hedera/errors.d.ts +4 -0
- package/lib/families/hedera/errors.d.ts.map +1 -0
- package/lib/families/hedera/errors.js +6 -0
- package/lib/families/hedera/errors.js.map +1 -0
- package/lib/families/hedera/specs.d.ts.map +1 -1
- package/lib/families/hedera/specs.js +0 -11
- package/lib/families/hedera/specs.js.map +1 -1
- package/lib/families/osmosis/specs.js +1 -1
- package/lib/families/polkadot/specs.d.ts.map +1 -1
- package/lib/families/polkadot/specs.js +1 -0
- package/lib/families/polkadot/specs.js.map +1 -1
- package/lib/families/solana/specs.d.ts.map +1 -1
- package/lib/families/solana/specs.js +1 -0
- package/lib/families/solana/specs.js.map +1 -1
- package/lib/families/tezos/bakers.whitelist-default.d.ts.map +1 -1
- package/lib/families/tezos/bakers.whitelist-default.js +1 -1
- package/lib/families/tezos/bakers.whitelist-default.js.map +1 -1
- package/lib/families/tezos/bridge/js.d.ts.map +1 -1
- package/lib/families/tezos/bridge/js.js +2 -1
- package/lib/families/tezos/bridge/js.js.map +1 -1
- package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib/featureFlags/defaultFeatures.js +6 -0
- package/lib/featureFlags/defaultFeatures.js.map +1 -1
- package/lib/hw/actions/app.d.ts +7 -0
- package/lib/hw/actions/app.d.ts.map +1 -1
- package/lib/hw/actions/app.js +25 -11
- package/lib/hw/actions/app.js.map +1 -1
- package/lib/hw/connectApp.d.ts +4 -0
- package/lib/hw/connectApp.d.ts.map +1 -1
- package/lib/hw/connectApp.js +10 -1
- package/lib/hw/connectApp.js.map +1 -1
- package/lib/manager/localization.d.ts +1 -1
- package/lib/manager/localization.d.ts.map +1 -1
- package/lib/manager/localization.js +1 -1
- package/lib/manager/localization.js.map +1 -1
- package/lib/rxjs/operators/retryWithDelay.d.ts +12 -0
- package/lib/rxjs/operators/retryWithDelay.d.ts.map +1 -0
- package/lib/rxjs/operators/retryWithDelay.js +28 -0
- package/lib/rxjs/operators/retryWithDelay.js.map +1 -0
- package/lib/rxjs/operators/throwIf.d.ts +23 -0
- package/lib/rxjs/operators/throwIf.d.ts.map +1 -0
- package/lib/rxjs/operators/throwIf.js +37 -0
- package/lib/rxjs/operators/throwIf.js.map +1 -0
- package/package.json +5 -5
- package/src/__tests__/environment.test.ts +12 -0
- package/src/__tests__/families/bitcoin/wallet-btc/xpub.syncing.integration.test.ts +0 -33
- package/src/account/support.ts +3 -2
- package/src/apps/hw.ts +17 -4
- package/src/apps/mock.ts +24 -2
- package/src/apps/runner.ts +28 -4
- package/src/apps/support.ts +1 -1
- package/src/bot/engine.ts +9 -1
- package/src/bot/index.ts +7 -2
- package/src/bot/types.ts +3 -0
- package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +33 -0
- package/src/data/icons/react/index.tsx +1 -0
- package/src/data/icons/react/yae.tsx +14 -0
- package/src/data/icons/reactNative/index.tsx +1 -0
- package/src/data/icons/reactNative/yae.tsx +15 -0
- package/src/data/icons/svg/YAE.svg +4 -0
- package/src/exchange/hw-app-exchange/Exchange.ts +4 -4
- package/src/families/algorand/__snapshots__/bridge.integration.test.ts.snap +807 -27
- package/src/families/bitcoin/account.ts +1 -1
- package/src/families/bitcoin/bech32m.ts +2 -2
- package/src/families/bitcoin/bridge/js.ts +6 -3
- package/src/families/bitcoin/bridge/mock.ts +6 -2
- package/src/families/bitcoin/js-getFeesForTransaction.ts +1 -1
- package/src/families/bitcoin/js-synchronisation.ts +0 -1
- package/src/families/bitcoin/logic.ts +5 -2
- package/src/families/bitcoin/presync.ts +1 -1
- package/src/families/bitcoin/specs.ts +1 -1
- package/src/families/bitcoin/wallet-btc/crypto/base.ts +0 -20
- package/src/families/bitcoin/wallet-btc/crypto/bip32.ts +6 -5
- package/src/families/bitcoin/wallet-btc/crypto/bitcoincash.ts +1 -9
- package/src/families/bitcoin/wallet-btc/crypto/factory.ts +1 -4
- package/src/families/bitcoin/wallet-btc/crypto/litecoin.ts +1 -20
- package/src/families/bitcoin/wallet-btc/crypto/types.ts +0 -3
- package/src/families/bitcoin/wallet-btc/crypto/zec.ts +1 -7
- package/src/families/bitcoin/wallet-btc/crypto/zen.ts +1 -7
- package/src/families/bitcoin/wallet-btc/explorer/index.ts +24 -49
- package/src/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.ts +6 -1
- package/src/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.ts +6 -1
- package/src/families/bitcoin/wallet-btc/pickingstrategies/Merge.ts +6 -1
- package/src/families/bitcoin/wallet-btc/storage/index.ts +34 -20
- package/src/families/bitcoin/wallet-btc/utils.ts +16 -21
- package/src/families/bitcoin/wallet-btc/wallet.ts +17 -31
- package/src/families/bitcoin/wallet-btc/xpub.ts +41 -150
- package/src/families/cardano/js-synchronisation.ts +1 -1
- package/src/families/cardano/specs.ts +1 -1
- package/src/families/celo/specs/createSendMutation.ts +1 -3
- package/src/families/celo/specs.ts +1 -1
- package/src/families/crypto_org/specs.ts +3 -2
- package/src/families/ethereum/specs.ts +3 -3
- package/src/families/evm/specs.ts +6 -6
- package/src/families/filecoin/__snapshots__/bridge.integration.test.ts.snap +24 -2
- package/src/families/filecoin/specs.ts +1 -2
- package/src/families/hedera/api/network.ts +10 -3
- package/src/families/hedera/errors.ts +5 -0
- package/src/families/hedera/specs.ts +0 -17
- package/src/families/osmosis/__snapshots__/bridge.integration.test.ts.snap +101 -3
- package/src/families/osmosis/specs.ts +1 -1
- package/src/families/polkadot/specs.ts +1 -0
- package/src/families/solana/specs.ts +1 -0
- package/src/families/tezos/bakers.whitelist-default.ts +0 -2
- package/src/families/tezos/bridge/js.ts +4 -1
- package/src/featureFlags/defaultFeatures.ts +6 -0
- package/src/hw/actions/app.ts +35 -4
- package/src/hw/connectApp.ts +18 -1
- package/src/manager/localization.ts +2 -2
- package/src/rxjs/operators/retryWithDelay.ts +36 -0
- package/src/rxjs/operators/throwIf.ts +40 -0
- package/lib/families/bitcoin/wallet-btc/utils/eventemitter.d.ts +0 -6
- package/lib/families/bitcoin/wallet-btc/utils/eventemitter.d.ts.map +0 -1
- package/lib/families/bitcoin/wallet-btc/utils/eventemitter.js +0 -64
- package/lib/families/bitcoin/wallet-btc/utils/eventemitter.js.map +0 -1
- package/src/families/bitcoin/wallet-btc/utils/eventemitter.ts +0 -9
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { maxBy, range, some } from "lodash";
|
|
2
2
|
import BigNumber from "bignumber.js";
|
|
3
3
|
import { TX, Address, IStorage } from "./storage/types";
|
|
4
|
-
import EventEmitter from "./utils/eventemitter";
|
|
5
4
|
import { IExplorer } from "./explorer/types";
|
|
6
5
|
import { ICrypto } from "./crypto/types";
|
|
7
6
|
import { PickingStrategy } from "./pickingstrategies/types";
|
|
@@ -9,7 +8,7 @@ import * as utils from "./utils";
|
|
|
9
8
|
import { TransactionInfo, InputInfo, OutputInfo } from "./types";
|
|
10
9
|
|
|
11
10
|
// names inside this class and discovery logic respect BIP32 standard
|
|
12
|
-
class Xpub
|
|
11
|
+
class Xpub {
|
|
13
12
|
storage: IStorage;
|
|
14
13
|
|
|
15
14
|
explorer: IExplorer;
|
|
@@ -30,8 +29,6 @@ class Xpub extends EventEmitter {
|
|
|
30
29
|
|
|
31
30
|
GAP = 20;
|
|
32
31
|
|
|
33
|
-
syncing: { [key: string]: boolean } = {};
|
|
34
|
-
|
|
35
32
|
// need to be bigger than the number of tx from the same address that can be in the same block
|
|
36
33
|
txsSyncArraySize = 1000;
|
|
37
34
|
|
|
@@ -48,7 +45,6 @@ class Xpub extends EventEmitter {
|
|
|
48
45
|
xpub: string;
|
|
49
46
|
derivationMode: string;
|
|
50
47
|
}) {
|
|
51
|
-
super();
|
|
52
48
|
this.storage = storage;
|
|
53
49
|
this.explorer = explorer;
|
|
54
50
|
this.crypto = crypto;
|
|
@@ -58,7 +54,7 @@ class Xpub extends EventEmitter {
|
|
|
58
54
|
this.freshAddressIndex = 0;
|
|
59
55
|
}
|
|
60
56
|
|
|
61
|
-
async syncAddress(account: number, index: number) {
|
|
57
|
+
async syncAddress(account: number, index: number): Promise<boolean> {
|
|
62
58
|
const address = await this.crypto.getAddress(
|
|
63
59
|
this.derivationMode,
|
|
64
60
|
this.xpub,
|
|
@@ -70,43 +66,22 @@ class Xpub extends EventEmitter {
|
|
|
70
66
|
`${this.crypto.network.name}-${this.derivationMode}-${this.xpub}-${account}-${index}`,
|
|
71
67
|
address
|
|
72
68
|
);
|
|
73
|
-
await this.whenSynced("address", address);
|
|
74
|
-
|
|
75
|
-
const data = {
|
|
76
|
-
type: "address",
|
|
77
|
-
key: address,
|
|
78
|
-
account,
|
|
79
|
-
index,
|
|
80
|
-
address,
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
this.emitSyncing(data);
|
|
84
69
|
|
|
85
70
|
// TODO handle eventual reorg case using lastBlock
|
|
71
|
+
// TODO perf: bad : looping in the tx array
|
|
72
|
+
await this.checkAddressReorg(account, index);
|
|
86
73
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
account,
|
|
97
|
-
index,
|
|
98
|
-
});
|
|
99
|
-
if (hasPendings) {
|
|
100
|
-
this.storage.removePendingTxs({ account, index });
|
|
101
|
-
}
|
|
102
|
-
total = await this.fetchHydrateAndStoreNewTxs(address, account, index);
|
|
103
|
-
} catch (e) {
|
|
104
|
-
this.emitSyncedFailed(data);
|
|
105
|
-
throw e;
|
|
74
|
+
// in case pendings have changed we clean them out
|
|
75
|
+
// TODO perf : bad : looping in the tx array
|
|
76
|
+
const hasPendings = !!this.storage.getLastTx({
|
|
77
|
+
confirmed: false,
|
|
78
|
+
account,
|
|
79
|
+
index,
|
|
80
|
+
});
|
|
81
|
+
if (hasPendings) {
|
|
82
|
+
this.storage.removePendingTxs({ account, index });
|
|
106
83
|
}
|
|
107
|
-
|
|
108
|
-
this.emitSynced({ ...data, total });
|
|
109
|
-
|
|
84
|
+
await this.fetchHydrateAndStoreNewTxs(address, account, index);
|
|
110
85
|
const lastTx = this.storage.getLastTx({
|
|
111
86
|
account,
|
|
112
87
|
index,
|
|
@@ -117,65 +92,31 @@ class Xpub extends EventEmitter {
|
|
|
117
92
|
return !!lastTx;
|
|
118
93
|
}
|
|
119
94
|
|
|
120
|
-
async checkAddressesBlock(account: number, index: number) {
|
|
95
|
+
async checkAddressesBlock(account: number, index: number): Promise<boolean> {
|
|
121
96
|
const addressesResults = await Promise.all(
|
|
122
97
|
range(this.GAP).map((_, key) => this.syncAddress(account, index + key))
|
|
123
98
|
);
|
|
124
99
|
return some(addressesResults, (lastTx) => !!lastTx);
|
|
125
100
|
}
|
|
126
101
|
|
|
127
|
-
async syncAccount(account: number) {
|
|
128
|
-
await this.whenSynced("account", account.toString());
|
|
129
|
-
|
|
130
|
-
this.emitSyncing({
|
|
131
|
-
type: "account",
|
|
132
|
-
key: account,
|
|
133
|
-
account,
|
|
134
|
-
});
|
|
135
|
-
|
|
102
|
+
async syncAccount(account: number): Promise<number> {
|
|
136
103
|
let index = 0;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
while (await this.checkAddressesBlock(account, index)) {
|
|
141
|
-
index += this.GAP;
|
|
142
|
-
}
|
|
143
|
-
} catch (e) {
|
|
144
|
-
this.emitSyncedFailed({
|
|
145
|
-
type: "account",
|
|
146
|
-
key: account,
|
|
147
|
-
account,
|
|
148
|
-
});
|
|
149
|
-
throw e;
|
|
104
|
+
// eslint-disable-next-line no-await-in-loop
|
|
105
|
+
while (await this.checkAddressesBlock(account, index)) {
|
|
106
|
+
index += this.GAP;
|
|
150
107
|
}
|
|
151
|
-
|
|
152
|
-
this.emitSynced({
|
|
153
|
-
type: "account",
|
|
154
|
-
key: account,
|
|
155
|
-
account,
|
|
156
|
-
index,
|
|
157
|
-
});
|
|
158
108
|
return index;
|
|
159
109
|
}
|
|
160
110
|
|
|
161
111
|
// TODO : test fail case + incremental
|
|
162
|
-
async sync() {
|
|
163
|
-
await this.whenSynced("all");
|
|
164
|
-
this.emitSyncing({ type: "all" });
|
|
112
|
+
async sync(): Promise<number> {
|
|
165
113
|
this.freshAddressIndex = 0;
|
|
166
114
|
let account = 0;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
account += 1;
|
|
172
|
-
}
|
|
173
|
-
} catch (e) {
|
|
174
|
-
this.emitSyncedFailed({ type: "all" });
|
|
175
|
-
throw e;
|
|
115
|
+
// eslint-disable-next-line no-await-in-loop
|
|
116
|
+
while (account < 2 && (await this.syncAccount(account))) {
|
|
117
|
+
// account=0 for receive address; account=1 for change address. No need to handle account>1
|
|
118
|
+
account += 1;
|
|
176
119
|
}
|
|
177
|
-
|
|
178
|
-
this.emitSynced({ type: "all", account });
|
|
179
120
|
this.freshAddress = await this.crypto.getAddress(
|
|
180
121
|
this.derivationMode,
|
|
181
122
|
this.xpub,
|
|
@@ -185,46 +126,33 @@ class Xpub extends EventEmitter {
|
|
|
185
126
|
return account;
|
|
186
127
|
}
|
|
187
128
|
|
|
188
|
-
async getXpubBalance() {
|
|
189
|
-
await this.whenSynced("all");
|
|
190
|
-
|
|
129
|
+
async getXpubBalance(): Promise<BigNumber> {
|
|
191
130
|
const addresses = await this.getXpubAddresses();
|
|
192
|
-
|
|
193
131
|
return this.getAddressesBalance(addresses);
|
|
194
132
|
}
|
|
195
133
|
|
|
196
|
-
async getAccountBalance(account: number) {
|
|
197
|
-
await this.whenSynced("account", account.toString());
|
|
198
|
-
|
|
134
|
+
async getAccountBalance(account: number): Promise<BigNumber> {
|
|
199
135
|
const addresses = await this.getAccountAddresses(account);
|
|
200
|
-
|
|
201
136
|
return this.getAddressesBalance(addresses);
|
|
202
137
|
}
|
|
203
138
|
|
|
204
|
-
async getAddressBalance(address: Address) {
|
|
205
|
-
await this.whenSynced("address", address.address);
|
|
206
|
-
|
|
139
|
+
async getAddressBalance(address: Address): Promise<BigNumber> {
|
|
207
140
|
const unspentUtxos = this.storage.getAddressUnspentUtxos(address);
|
|
208
|
-
|
|
209
141
|
return unspentUtxos.reduce(
|
|
210
142
|
(total, { value }) => total.plus(value),
|
|
211
143
|
new BigNumber(0)
|
|
212
144
|
);
|
|
213
145
|
}
|
|
214
146
|
|
|
215
|
-
async getXpubAddresses() {
|
|
216
|
-
await this.whenSynced("all");
|
|
147
|
+
async getXpubAddresses(): Promise<Address[]> {
|
|
217
148
|
return this.storage.getUniquesAddresses({});
|
|
218
149
|
}
|
|
219
150
|
|
|
220
|
-
async getAccountAddresses(account: number) {
|
|
221
|
-
await this.whenSynced("account", account.toString());
|
|
151
|
+
async getAccountAddresses(account: number): Promise<Address[]> {
|
|
222
152
|
return this.storage.getUniquesAddresses({ account });
|
|
223
153
|
}
|
|
224
154
|
|
|
225
|
-
async getNewAddress(account: number, gap: number) {
|
|
226
|
-
await this.whenSynced("account", account.toString());
|
|
227
|
-
|
|
155
|
+
async getNewAddress(account: number, gap: number): Promise<Address> {
|
|
228
156
|
const accountAddresses = await this.getAccountAddresses(account);
|
|
229
157
|
const lastIndex = (maxBy(accountAddresses, "index") || { index: -1 }).index;
|
|
230
158
|
let index: number;
|
|
@@ -254,8 +182,6 @@ class Xpub extends EventEmitter {
|
|
|
254
182
|
utxoPickingStrategy: PickingStrategy;
|
|
255
183
|
sequence: number;
|
|
256
184
|
}): Promise<TransactionInfo> {
|
|
257
|
-
await this.whenSynced("all");
|
|
258
|
-
|
|
259
185
|
const outputs: OutputInfo[] = [];
|
|
260
186
|
|
|
261
187
|
// outputs splitting
|
|
@@ -318,9 +244,12 @@ class Xpub extends EventEmitter {
|
|
|
318
244
|
};
|
|
319
245
|
});
|
|
320
246
|
const associatedDerivations: [number, number][] = unspentUtxoSelected.map(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
247
|
+
(_utxo, index) => {
|
|
248
|
+
if (txs[index] == null) {
|
|
249
|
+
throw new Error("Invalid index in txs[index]");
|
|
250
|
+
}
|
|
251
|
+
return [txs[index]?.account || 0, txs[index]?.index || 0];
|
|
252
|
+
}
|
|
324
253
|
);
|
|
325
254
|
|
|
326
255
|
const txSize = utils.maxTxSizeCeil(
|
|
@@ -334,7 +263,7 @@ class Xpub extends EventEmitter {
|
|
|
334
263
|
// Abandon the change output if change output amount is less than dust amount
|
|
335
264
|
if (
|
|
336
265
|
needChangeoutput &&
|
|
337
|
-
total.minus(params.amount).minus(fee)
|
|
266
|
+
total.minus(params.amount).minus(fee).gt(dustAmount)
|
|
338
267
|
) {
|
|
339
268
|
outputs.push({
|
|
340
269
|
script: this.crypto.toOutputScript(params.changeAddress.address),
|
|
@@ -358,12 +287,12 @@ class Xpub extends EventEmitter {
|
|
|
358
287
|
};
|
|
359
288
|
}
|
|
360
289
|
|
|
361
|
-
async broadcastTx(rawTxHex: string) {
|
|
290
|
+
async broadcastTx(rawTxHex: string): Promise<any> {
|
|
362
291
|
return this.explorer.broadcast(rawTxHex);
|
|
363
292
|
}
|
|
364
293
|
|
|
365
294
|
// internal
|
|
366
|
-
async getAddressesBalance(addresses: Address[]) {
|
|
295
|
+
async getAddressesBalance(addresses: Address[]): Promise<BigNumber> {
|
|
367
296
|
const balances = await Promise.all(
|
|
368
297
|
addresses.map((address) => this.getAddressBalance(address))
|
|
369
298
|
);
|
|
@@ -374,49 +303,11 @@ class Xpub extends EventEmitter {
|
|
|
374
303
|
);
|
|
375
304
|
}
|
|
376
305
|
|
|
377
|
-
// TODO : test the different syncing protection logic
|
|
378
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
379
|
-
emitSyncing(data: any) {
|
|
380
|
-
this.syncing[`${data.type}-${data.key}`] = true;
|
|
381
|
-
this.emit("syncing", data);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
385
|
-
emitSynced(data: any) {
|
|
386
|
-
this.syncing[`${data.type}-${data.key}`] = false;
|
|
387
|
-
this.emit("synced", data);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
391
|
-
emitSyncedFailed(data: any) {
|
|
392
|
-
this.syncing[`${data.type}-${data.key}`] = false;
|
|
393
|
-
this.emit("syncfail", data);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
whenSynced(type: string, key?: string): Promise<void> {
|
|
397
|
-
return new Promise((resolve) => {
|
|
398
|
-
if (!this.syncing[`${type}-${key}`]) {
|
|
399
|
-
resolve();
|
|
400
|
-
} else {
|
|
401
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
402
|
-
const handler = (evt: any) => {
|
|
403
|
-
if (evt.type === type && evt.key === key) {
|
|
404
|
-
resolve();
|
|
405
|
-
this.removeListener("synced", handler);
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
409
|
-
// @ts-ignore
|
|
410
|
-
this.on("synced", handler);
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
|
|
415
306
|
async fetchHydrateAndStoreNewTxs(
|
|
416
307
|
address: string,
|
|
417
308
|
account: number,
|
|
418
309
|
index: number
|
|
419
|
-
) {
|
|
310
|
+
): Promise<number> {
|
|
420
311
|
let pendingTxs: TX[] = [];
|
|
421
312
|
let txs: TX[] = [];
|
|
422
313
|
let inserted = 0;
|
|
@@ -441,7 +332,7 @@ class Xpub extends EventEmitter {
|
|
|
441
332
|
return inserted;
|
|
442
333
|
}
|
|
443
334
|
|
|
444
|
-
async checkAddressReorg(account: number, index: number) {
|
|
335
|
+
async checkAddressReorg(account: number, index: number): Promise<void> {
|
|
445
336
|
const lastTx = this.storage.getLastTx({
|
|
446
337
|
account,
|
|
447
338
|
index,
|
|
@@ -232,7 +232,7 @@ export const getAccountShape: GetAccountShape = async (
|
|
|
232
232
|
newTransactions,
|
|
233
233
|
tokens: tokenBalance,
|
|
234
234
|
accountCredentialsMap,
|
|
235
|
-
});
|
|
235
|
+
}).filter((a) => !blacklistedTokenIds?.includes(a.token.id));
|
|
236
236
|
|
|
237
237
|
const newOperations = newTransactions.map((t) =>
|
|
238
238
|
mapTxToAccountOperation(t, accountId, accountCredentialsMap, subAccounts)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import invariant from "invariant";
|
|
2
2
|
import { getCryptoCurrencyById, parseCurrencyUnit } from "../../../currencies";
|
|
3
|
-
import {
|
|
3
|
+
import { pickSiblings } from "../../../bot/specs";
|
|
4
4
|
import { MutationSpec } from "../../../bot/types";
|
|
5
5
|
import type { Transaction } from "../types";
|
|
6
6
|
|
|
@@ -11,7 +11,6 @@ export const minimalAmount = parseCurrencyUnit(currency.units[0], "0.001");
|
|
|
11
11
|
export const createSend50PercentMutation = (): MutationSpec<Transaction> => ({
|
|
12
12
|
name: "Celo: Move 50% to another account",
|
|
13
13
|
maxRun: 1,
|
|
14
|
-
testDestination: genericTestDestination,
|
|
15
14
|
transaction: ({ account, siblings, bridge, maxSpendable }) => {
|
|
16
15
|
invariant(
|
|
17
16
|
maxSpendable.gt(minimalAmount),
|
|
@@ -30,7 +29,6 @@ export const createSend50PercentMutation = (): MutationSpec<Transaction> => ({
|
|
|
30
29
|
export const createSendMaxMutation = (): MutationSpec<Transaction> => ({
|
|
31
30
|
name: "Celo: Send max to another account",
|
|
32
31
|
maxRun: 1,
|
|
33
|
-
testDestination: genericTestDestination,
|
|
34
32
|
transaction: ({ account, siblings, bridge, maxSpendable }) => {
|
|
35
33
|
invariant(
|
|
36
34
|
maxSpendable.gt(minimalAmount),
|
|
@@ -31,7 +31,8 @@ const sharedMutations = ({ maxAccount }) => [
|
|
|
31
31
|
];
|
|
32
32
|
|
|
33
33
|
const crypto_org_croeseid: AppSpec<Transaction> = {
|
|
34
|
-
|
|
34
|
+
disabled: true, // explorers are not correctly working. we will focus on crypto_org spec for now
|
|
35
|
+
name: "Crypto org Testnet",
|
|
35
36
|
currency: getCryptoCurrencyById("crypto_org_croeseid"),
|
|
36
37
|
appQuery: {
|
|
37
38
|
model: DeviceModelId.nanoS,
|
|
@@ -45,7 +46,7 @@ const crypto_org_croeseid: AppSpec<Transaction> = {
|
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
const crypto_org: AppSpec<Transaction> = {
|
|
48
|
-
name: "Crypto
|
|
49
|
+
name: "Crypto org",
|
|
49
50
|
currency: getCryptoCurrencyById("crypto_org"),
|
|
50
51
|
appQuery: {
|
|
51
52
|
model: DeviceModelId.nanoS,
|
|
@@ -21,7 +21,7 @@ import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
|
21
21
|
import { CompoundAccountSummary } from "../../compound/types";
|
|
22
22
|
import { acceptTransaction } from "./speculos-deviceActions";
|
|
23
23
|
|
|
24
|
-
const testTimeout =
|
|
24
|
+
const testTimeout = 8 * 60 * 1000;
|
|
25
25
|
|
|
26
26
|
const ethereumBasicMutations = ({ maxAccount }) => [
|
|
27
27
|
{
|
|
@@ -131,7 +131,7 @@ const ethereum: AppSpec<Transaction> = {
|
|
|
131
131
|
appQuery: {
|
|
132
132
|
model: DeviceModelId.nanoS,
|
|
133
133
|
appName: "Ethereum",
|
|
134
|
-
appVersion: "1.9.20
|
|
134
|
+
appVersion: "1.9.20",
|
|
135
135
|
},
|
|
136
136
|
genericDeviceAction: acceptTransaction,
|
|
137
137
|
testTimeout,
|
|
@@ -403,7 +403,7 @@ const ethereumGoerli: AppSpec<Transaction> = {
|
|
|
403
403
|
appQuery: {
|
|
404
404
|
model: DeviceModelId.nanoS,
|
|
405
405
|
appName: "Ethereum",
|
|
406
|
-
appVersion: "1.9.20
|
|
406
|
+
appVersion: "1.9.20",
|
|
407
407
|
},
|
|
408
408
|
genericDeviceAction: acceptTransaction,
|
|
409
409
|
testTimeout,
|
|
@@ -7,7 +7,7 @@ import { botTest, genericTestDestination, pickSiblings } from "../../bot/specs";
|
|
|
7
7
|
import type { AppSpec } from "../../bot/types";
|
|
8
8
|
import type { Transaction } from "./types";
|
|
9
9
|
|
|
10
|
-
const testTimeout =
|
|
10
|
+
const testTimeout = 6 * 60 * 1000;
|
|
11
11
|
|
|
12
12
|
const transactionCheck =
|
|
13
13
|
(currencyId: string) =>
|
|
@@ -68,7 +68,7 @@ const cronos: AppSpec<Transaction> = {
|
|
|
68
68
|
appQuery: {
|
|
69
69
|
model: DeviceModelId.nanoS,
|
|
70
70
|
appName: "Ethereum",
|
|
71
|
-
appVersion: "1.9.20
|
|
71
|
+
appVersion: "1.9.20",
|
|
72
72
|
},
|
|
73
73
|
testTimeout,
|
|
74
74
|
transactionCheck: transactionCheck("cronos"),
|
|
@@ -84,7 +84,7 @@ const fantom: AppSpec<Transaction> = {
|
|
|
84
84
|
appQuery: {
|
|
85
85
|
model: DeviceModelId.nanoS,
|
|
86
86
|
appName: "Ethereum",
|
|
87
|
-
appVersion: "1.9.20
|
|
87
|
+
appVersion: "1.9.20",
|
|
88
88
|
},
|
|
89
89
|
testTimeout,
|
|
90
90
|
transactionCheck: transactionCheck("fantom"),
|
|
@@ -100,7 +100,7 @@ const moonbeam: AppSpec<Transaction> = {
|
|
|
100
100
|
appQuery: {
|
|
101
101
|
model: DeviceModelId.nanoS,
|
|
102
102
|
appName: "Ethereum",
|
|
103
|
-
appVersion: "1.9.20
|
|
103
|
+
appVersion: "1.9.20",
|
|
104
104
|
},
|
|
105
105
|
testTimeout,
|
|
106
106
|
transactionCheck: transactionCheck("moonbeam"),
|
|
@@ -116,7 +116,7 @@ const songbird: AppSpec<Transaction> = {
|
|
|
116
116
|
appQuery: {
|
|
117
117
|
model: DeviceModelId.nanoS,
|
|
118
118
|
appName: "Ethereum",
|
|
119
|
-
appVersion: "1.9.20
|
|
119
|
+
appVersion: "1.9.20",
|
|
120
120
|
},
|
|
121
121
|
testTimeout,
|
|
122
122
|
transactionCheck: transactionCheck("songbird"),
|
|
@@ -132,7 +132,7 @@ const flare: AppSpec<Transaction> = {
|
|
|
132
132
|
appQuery: {
|
|
133
133
|
model: DeviceModelId.nanoS,
|
|
134
134
|
appName: "Ethereum",
|
|
135
|
-
appVersion: "1.9.20
|
|
135
|
+
appVersion: "1.9.20",
|
|
136
136
|
},
|
|
137
137
|
testTimeout,
|
|
138
138
|
transactionCheck: transactionCheck("flare"),
|
|
@@ -18,7 +18,7 @@ Array [
|
|
|
18
18
|
"index": 0,
|
|
19
19
|
"name": "Filecoin 1",
|
|
20
20
|
"nfts": undefined,
|
|
21
|
-
"operationsCount":
|
|
21
|
+
"operationsCount": 1,
|
|
22
22
|
"pendingOperations": Array [],
|
|
23
23
|
"seedIdentifier": "04ca7b02cafdf36e8b4caaf530a96b949764af71b956b2a3328b7a10940794c860f574a9199be98bde3c261887fec8e5fd94bc5f104908bf5f992f52ef2a89abb0",
|
|
24
24
|
"spendableBalance": "1000000000000000",
|
|
@@ -85,7 +85,29 @@ Array [
|
|
|
85
85
|
|
|
86
86
|
exports[`filecoin currency bridge scanAccounts filecoin seed 1 2`] = `
|
|
87
87
|
Array [
|
|
88
|
-
Array [
|
|
88
|
+
Array [
|
|
89
|
+
Object {
|
|
90
|
+
"accountId": "js:2:filecoin:t15lauyzdivqj7m3yob3rxmzdsy7uyhfflwyheuri:gliflegacy",
|
|
91
|
+
"blockHash": null,
|
|
92
|
+
"blockHeight": 1899682,
|
|
93
|
+
"contract": undefined,
|
|
94
|
+
"extra": Object {},
|
|
95
|
+
"fee": "0",
|
|
96
|
+
"hash": "bafy2bzaceawypi647m4rz5czma3xm7syif67bfzce5q2w2tifd5jrvqeaowok",
|
|
97
|
+
"id": "js:2:filecoin:t15lauyzdivqj7m3yob3rxmzdsy7uyhfflwyheuri:gliflegacy-bafy2bzaceawypi647m4rz5czma3xm7syif67bfzce5q2w2tifd5jrvqeaowok-IN",
|
|
98
|
+
"operator": undefined,
|
|
99
|
+
"recipients": Array [
|
|
100
|
+
"t15lauyzdivqj7m3yob3rxmzdsy7uyhfflwyheuri",
|
|
101
|
+
],
|
|
102
|
+
"senders": Array [
|
|
103
|
+
"f1ov6d42tujoyexkbdh34oik2vhe5unqo2a5ocqoq",
|
|
104
|
+
],
|
|
105
|
+
"standard": undefined,
|
|
106
|
+
"tokenId": undefined,
|
|
107
|
+
"type": "IN",
|
|
108
|
+
"value": "1000000000000000",
|
|
109
|
+
},
|
|
110
|
+
],
|
|
89
111
|
Array [
|
|
90
112
|
Object {
|
|
91
113
|
"accountId": "js:2:filecoin:f1p74d4mlmeyc4agflhjqsnvoyzyfdai7fmkyso2a:",
|
|
@@ -19,7 +19,7 @@ const filecoinSpecs: AppSpec<Transaction> = {
|
|
|
19
19
|
appName: "Filecoin",
|
|
20
20
|
},
|
|
21
21
|
genericDeviceAction: acceptTransaction,
|
|
22
|
-
testTimeout:
|
|
22
|
+
testTimeout: 6 * 60 * 1000,
|
|
23
23
|
minViableAmount: MIN_SAFE,
|
|
24
24
|
transactionCheck: ({ maxSpendable }) => {
|
|
25
25
|
invariant(maxSpendable.gt(MIN_SAFE), "balance is too low");
|
|
@@ -59,7 +59,6 @@ const filecoinSpecs: AppSpec<Transaction> = {
|
|
|
59
59
|
{
|
|
60
60
|
name: "Transfer Max",
|
|
61
61
|
maxRun: 1,
|
|
62
|
-
testDestination: genericTestDestination,
|
|
63
62
|
transaction: ({ account, siblings, bridge }) => {
|
|
64
63
|
return {
|
|
65
64
|
transaction: bridge.createTransaction(account),
|
|
@@ -3,6 +3,7 @@ import * as hedera from "@hashgraph/sdk";
|
|
|
3
3
|
import { Account } from "@ledgerhq/types-live";
|
|
4
4
|
import { Transaction } from "../types";
|
|
5
5
|
import { AccountId } from "@hashgraph/sdk";
|
|
6
|
+
import { HederaAddAccountError } from "../errors";
|
|
6
7
|
|
|
7
8
|
export function broadcastTransaction(
|
|
8
9
|
transaction: hedera.Transaction
|
|
@@ -37,9 +38,15 @@ export async function getAccountBalance(
|
|
|
37
38
|
address: string
|
|
38
39
|
): Promise<AccountBalance> {
|
|
39
40
|
const accountId = AccountId.fromString(address);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
let accountBalance;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
accountBalance = await new hedera.AccountBalanceQuery({
|
|
45
|
+
accountId,
|
|
46
|
+
}).execute(getClient());
|
|
47
|
+
} catch {
|
|
48
|
+
throw new HederaAddAccountError();
|
|
49
|
+
}
|
|
43
50
|
|
|
44
51
|
return {
|
|
45
52
|
balance: accountBalance.hbars.to(hedera.HbarUnit.Tinybar),
|
|
@@ -102,23 +102,6 @@ const hedera: AppSpec<Transaction> = {
|
|
|
102
102
|
updates: [{ recipient }, { useAllAmount: true }],
|
|
103
103
|
};
|
|
104
104
|
},
|
|
105
|
-
test: ({
|
|
106
|
-
accountBeforeTransaction,
|
|
107
|
-
account,
|
|
108
|
-
operation,
|
|
109
|
-
transaction,
|
|
110
|
-
}: TransactionTestInput<Transaction>): void => {
|
|
111
|
-
const accountBalanceAfterTx = account.balance.toNumber();
|
|
112
|
-
|
|
113
|
-
// NOTE: operation.fee is the ACTUAL (not estimated) fee cost of the transaction
|
|
114
|
-
const amount = accountBeforeTransaction.balance
|
|
115
|
-
.minus(transaction.amount.plus(operation.fee))
|
|
116
|
-
.toNumber();
|
|
117
|
-
|
|
118
|
-
botTest("account balance moved with operation", () =>
|
|
119
|
-
expect(accountBalanceAfterTx).toBe(amount)
|
|
120
|
-
);
|
|
121
|
-
},
|
|
122
105
|
},
|
|
123
106
|
{
|
|
124
107
|
name: "Memo",
|