@ledgerhq/live-common 21.22.0 → 21.24.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/lib/account/formatters.d.ts.map +1 -1
- package/lib/account/formatters.js +1 -0
- package/lib/account/formatters.js.map +1 -1
- package/lib/account/support.d.ts.map +1 -1
- package/lib/account/support.js +1 -0
- package/lib/account/support.js.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 +4 -2
- package/lib/data/icons/react/index.js.map +1 -1
- package/lib/data/icons/react/sol.js +4 -2
- package/lib/data/icons/react/sol.js.map +1 -1
- package/lib/data/icons/react/ssv.d.ts +8 -0
- package/lib/data/icons/react/ssv.d.ts.map +1 -0
- package/lib/data/icons/react/ssv.js +31 -0
- package/lib/data/icons/react/ssv.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 +4 -2
- package/lib/data/icons/reactNative/index.js.map +1 -1
- package/lib/data/icons/reactNative/sol.js +4 -2
- package/lib/data/icons/reactNative/sol.js.map +1 -1
- package/lib/data/icons/reactNative/ssv.d.ts +8 -0
- package/lib/data/icons/reactNative/ssv.d.ts.map +1 -0
- package/lib/data/icons/reactNative/ssv.js +32 -0
- package/lib/data/icons/reactNative/ssv.js.map +1 -0
- package/lib/derivation.d.ts.map +1 -1
- package/lib/derivation.js +0 -3
- package/lib/derivation.js.map +1 -1
- package/lib/env.d.ts +10 -10
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +5 -5
- package/lib/env.js.map +1 -1
- package/lib/env.react.d.ts +1 -1
- package/lib/env.react.d.ts.map +1 -1
- package/lib/families/algorand/account.d.ts.map +1 -1
- package/lib/families/algorand/account.js +0 -4
- package/lib/families/algorand/account.js.map +1 -1
- package/lib/families/algorand/api/algodv2.d.ts +5 -0
- package/lib/families/algorand/api/algodv2.d.ts.map +1 -0
- package/lib/families/algorand/api/algodv2.js +118 -0
- package/lib/families/algorand/api/algodv2.js.map +1 -0
- package/lib/families/algorand/api/algodv2.types.d.ts +24 -0
- package/lib/families/algorand/api/algodv2.types.d.ts.map +1 -0
- package/lib/families/algorand/api/algodv2.types.js +3 -0
- package/lib/families/algorand/api/algodv2.types.js.map +1 -0
- package/lib/families/algorand/api/index.d.ts +5 -0
- package/lib/families/algorand/api/index.d.ts.map +1 -0
- package/lib/families/algorand/api/index.js +17 -0
- package/lib/families/algorand/api/index.js.map +1 -0
- package/lib/families/algorand/api/indexer.d.ts +3 -0
- package/lib/families/algorand/api/indexer.d.ts.map +1 -0
- package/lib/families/algorand/api/indexer.js +134 -0
- package/lib/families/algorand/api/indexer.js.map +1 -0
- package/lib/families/algorand/api/indexer.types.d.ts +35 -0
- package/lib/families/algorand/api/indexer.types.d.ts.map +1 -0
- package/lib/families/algorand/api/indexer.types.js +10 -0
- package/lib/families/algorand/api/indexer.types.js.map +1 -0
- package/lib/families/algorand/bridge/js.d.ts +8 -0
- package/lib/families/algorand/bridge/js.d.ts.map +1 -0
- package/lib/families/algorand/bridge/js.js +85 -0
- package/lib/families/algorand/bridge/js.js.map +1 -0
- package/lib/families/algorand/bridge/libcore.d.ts +3 -3
- package/lib/families/algorand/bridge/libcore.d.ts.map +1 -1
- package/lib/families/algorand/bridge/libcore.js.map +1 -1
- package/lib/families/algorand/bridge/mock.d.ts +2 -2
- package/lib/families/algorand/bridge/mock.d.ts.map +1 -1
- package/lib/families/algorand/bridge/mock.js.map +1 -1
- package/lib/families/algorand/buildTransaction.d.ts +8 -0
- package/lib/families/algorand/buildTransaction.d.ts.map +1 -0
- package/lib/families/algorand/buildTransaction.js +101 -0
- package/lib/families/algorand/buildTransaction.js.map +1 -0
- package/lib/families/algorand/cli-transaction.js +1 -1
- package/lib/families/algorand/cli-transaction.js.map +1 -1
- package/lib/families/algorand/deviceTransactionConfig.d.ts +2 -2
- package/lib/families/algorand/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/families/algorand/deviceTransactionConfig.js +0 -13
- package/lib/families/algorand/deviceTransactionConfig.js.map +1 -1
- package/lib/families/algorand/hw-getAddress.d.ts.map +1 -1
- package/lib/families/algorand/hw-getAddress.js +2 -24
- package/lib/families/algorand/hw-getAddress.js.map +1 -1
- package/lib/families/algorand/js-broadcast.d.ts +9 -0
- package/lib/families/algorand/js-broadcast.d.ts.map +1 -0
- package/lib/families/algorand/js-broadcast.js +63 -0
- package/lib/families/algorand/js-broadcast.js.map +1 -0
- package/lib/families/algorand/js-estimateMaxSpendable.d.ts +9 -0
- package/lib/families/algorand/js-estimateMaxSpendable.d.ts.map +1 -0
- package/lib/families/algorand/js-estimateMaxSpendable.js +89 -0
- package/lib/families/algorand/js-estimateMaxSpendable.js.map +1 -0
- package/lib/families/algorand/js-getFeesForTransaction.d.ts +5 -0
- package/lib/families/algorand/js-getFeesForTransaction.d.ts.map +1 -0
- package/lib/families/algorand/js-getFeesForTransaction.js +69 -0
- package/lib/families/algorand/js-getFeesForTransaction.js.map +1 -0
- package/lib/families/algorand/js-getTransactionStatus.d.ts +11 -0
- package/lib/families/algorand/js-getTransactionStatus.d.ts.map +1 -0
- package/lib/families/algorand/js-getTransactionStatus.js +201 -0
- package/lib/families/algorand/js-getTransactionStatus.js.map +1 -0
- package/lib/families/algorand/js-prepareTransaction.d.ts +5 -0
- package/lib/families/algorand/js-prepareTransaction.d.ts.map +1 -0
- package/lib/families/algorand/js-prepareTransaction.js +101 -0
- package/lib/families/algorand/js-prepareTransaction.js.map +1 -0
- package/lib/families/algorand/js-signOperation.d.ts +10 -0
- package/lib/families/algorand/js-signOperation.d.ts.map +1 -0
- package/lib/families/algorand/js-signOperation.js +164 -0
- package/lib/families/algorand/js-signOperation.js.map +1 -0
- package/lib/families/algorand/js-synchronization.d.ts +10 -0
- package/lib/families/algorand/js-synchronization.d.ts.map +1 -0
- package/lib/families/algorand/js-synchronization.js +411 -0
- package/lib/families/algorand/js-synchronization.js.map +1 -0
- package/lib/families/algorand/libcore-buildTransaction.d.ts +2 -2
- package/lib/families/algorand/libcore-buildTransaction.d.ts.map +1 -1
- package/lib/families/algorand/libcore-getFeesForTransaction.d.ts +4 -4
- package/lib/families/algorand/libcore-getFeesForTransaction.d.ts.map +1 -1
- package/lib/families/algorand/libcore-getFeesForTransaction.js +2 -2
- package/lib/families/algorand/libcore-getFeesForTransaction.js.map +1 -1
- package/lib/families/algorand/libcore-postBuildAccount.d.ts.map +1 -1
- package/lib/families/algorand/libcore-postBuildAccount.js +5 -11
- package/lib/families/algorand/libcore-postBuildAccount.js.map +1 -1
- package/lib/families/algorand/libcore-signOperation.d.ts +2 -2
- package/lib/families/algorand/libcore-signOperation.d.ts.map +1 -1
- package/lib/families/algorand/libcore-signOperation.js.map +1 -1
- package/lib/families/algorand/logic.d.ts +10 -0
- package/lib/families/algorand/logic.d.ts.map +1 -1
- package/lib/families/algorand/logic.js +79 -1
- package/lib/families/algorand/logic.js.map +1 -1
- package/lib/families/algorand/mock.d.ts.map +1 -1
- package/lib/families/algorand/mock.js +4 -11
- package/lib/families/algorand/mock.js.map +1 -1
- package/lib/families/algorand/serialization.js +4 -4
- package/lib/families/algorand/serialization.js.map +1 -1
- package/lib/families/algorand/specs.d.ts +2 -2
- package/lib/families/algorand/specs.d.ts.map +1 -1
- package/lib/families/algorand/specs.js +8 -16
- package/lib/families/algorand/specs.js.map +1 -1
- package/lib/families/algorand/speculos-deviceActions.d.ts +2 -2
- package/lib/families/algorand/speculos-deviceActions.d.ts.map +1 -1
- package/lib/families/algorand/speculos-deviceActions.js +4 -0
- package/lib/families/algorand/speculos-deviceActions.js.map +1 -1
- package/lib/families/algorand/test-dataset.d.ts +2 -2
- package/lib/families/algorand/test-dataset.d.ts.map +1 -1
- package/lib/families/algorand/test-dataset.js +1 -2
- package/lib/families/algorand/test-dataset.js.map +1 -1
- package/lib/families/algorand/tokens.d.ts.map +1 -1
- package/lib/families/algorand/tokens.js.map +1 -1
- package/lib/families/algorand/transaction.d.ts +5 -5
- package/lib/families/algorand/transaction.d.ts.map +1 -1
- package/lib/families/algorand/transaction.js.map +1 -1
- package/lib/families/algorand/types.d.ts +7 -5
- package/lib/families/algorand/types.d.ts.map +1 -1
- package/lib/families/algorand/types.js.map +1 -1
- package/lib/families/bitcoin/js-prepareTransaction.d.ts.map +1 -1
- package/lib/families/bitcoin/js-prepareTransaction.js +3 -2
- package/lib/families/bitcoin/js-prepareTransaction.js.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.js +13 -14
- package/lib/families/bitcoin/js-synchronisation.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/base.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/base.js +30 -22
- package/lib/families/bitcoin/wallet-btc/crypto/base.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.d.ts +11 -0
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.d.ts.map +1 -0
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.js +32 -0
- package/lib/families/bitcoin/wallet-btc/crypto/bip32.js.map +1 -0
- package/lib/families/bitcoin/wallet-btc/crypto/decred.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/crypto/decred.js +3 -115
- package/lib/families/bitcoin/wallet-btc/crypto/decred.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/index.d.ts +24 -8
- package/lib/families/bitcoin/wallet-btc/storage/index.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/index.js +114 -128
- package/lib/families/bitcoin/wallet-btc/storage/index.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/types.d.ts +8 -7
- package/lib/families/bitcoin/wallet-btc/storage/types.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/xpub.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/xpub.js +42 -63
- package/lib/families/bitcoin/wallet-btc/xpub.js.map +1 -1
- package/lib/families/tezos/bridge/js.d.ts.map +1 -1
- package/lib/families/tezos/bridge/js.js +38 -17
- package/lib/families/tezos/bridge/js.js.map +1 -1
- package/lib/families/tezos/signOperation.d.ts.map +1 -1
- package/lib/families/tezos/signOperation.js +9 -0
- package/lib/families/tezos/signOperation.js.map +1 -1
- package/lib/families/tezos/synchronisation.js +1 -1
- package/lib/families/tezos/synchronisation.js.map +1 -1
- package/lib/generated/bridge/js.d.ts +4 -0
- package/lib/generated/bridge/js.d.ts.map +1 -1
- package/lib/generated/bridge/js.js +26 -24
- package/lib/generated/bridge/js.js.map +1 -1
- package/lib/generated/bridge/libcore.d.ts +1 -1
- package/lib/generated/bridge/mock.d.ts +1 -1
- package/lib/generated/specs.d.ts +1 -1
- package/lib/generated/speculos-deviceActions.d.ts +1 -1
- package/lib/generated/test-dataset.d.ts +1 -1
- package/lib/generated/transaction.d.ts +3 -3
- package/lib/libcore/buildAccount/index.d.ts.map +1 -1
- package/lib/libcore/buildAccount/index.js +0 -1
- package/lib/libcore/buildAccount/index.js.map +1 -1
- package/lib/mock/account.js +21 -21
- package/lib/mock/account.js.map +1 -1
- package/lib/types/operation.d.ts +1 -1
- package/lib/types/operation.d.ts.map +1 -1
- package/package.json +4 -3
- package/src/__tests__/__snapshots__/all.libcore.ts.snap +7 -114
- package/src/account/formatters.ts +1 -0
- package/src/account/support.ts +1 -0
- package/src/data/icons/react/index.tsx +1 -0
- package/src/data/icons/react/sol.tsx +1 -1
- package/src/data/icons/react/ssv.tsx +12 -0
- package/src/data/icons/reactNative/index.tsx +1 -0
- package/src/data/icons/reactNative/sol.tsx +1 -1
- package/src/data/icons/reactNative/ssv.tsx +13 -0
- package/src/data/icons/svg/SOL.svg +1 -3
- package/src/data/icons/svg/SSV.svg +4 -0
- package/src/derivation.ts +0 -2
- package/src/env.ts +5 -5
- package/src/families/algorand/account.ts +0 -9
- package/src/families/algorand/api/algodv2.ts +68 -0
- package/src/families/algorand/api/algodv2.types.ts +27 -0
- package/src/families/algorand/api/index.ts +4 -0
- package/src/families/algorand/api/indexer.ts +99 -0
- package/src/families/algorand/api/indexer.types.ts +41 -0
- package/src/families/algorand/bridge/js.ts +46 -0
- package/src/families/algorand/bridge/libcore.ts +4 -4
- package/src/families/algorand/bridge/mock.ts +3 -3
- package/src/families/algorand/buildTransaction.ts +100 -0
- package/src/families/algorand/cli-transaction.ts +1 -1
- package/src/families/algorand/deviceTransactionConfig.ts +2 -16
- package/src/families/algorand/hw-getAddress.ts +1 -10
- package/src/families/algorand/js-broadcast.ts +17 -0
- package/src/families/algorand/js-estimateMaxSpendable.ts +51 -0
- package/src/families/algorand/js-getFeesForTransaction.ts +25 -0
- package/src/families/algorand/js-getTransactionStatus.ts +178 -0
- package/src/families/algorand/js-prepareTransaction.ts +42 -0
- package/src/families/algorand/js-signOperation.ts +145 -0
- package/src/families/algorand/js-synchronization.ts +433 -0
- package/src/families/algorand/libcore-buildTransaction.ts +2 -2
- package/src/families/algorand/libcore-getFeesForTransaction.ts +4 -4
- package/src/families/algorand/libcore-postBuildAccount.ts +2 -7
- package/src/families/algorand/libcore-signOperation.ts +2 -2
- package/src/families/algorand/logic.ts +47 -0
- package/src/families/algorand/mock.ts +2 -12
- package/src/families/algorand/serialization.ts +4 -4
- package/src/families/algorand/specs.ts +16 -22
- package/src/families/algorand/speculos-deviceActions.ts +87 -82
- package/src/families/algorand/test-dataset.ts +5 -6
- package/src/families/algorand/tokens.ts +1 -0
- package/src/families/algorand/transaction.ts +13 -4
- package/src/families/algorand/types.ts +10 -5
- package/src/families/bitcoin/js-prepareTransaction.ts +3 -2
- package/src/families/bitcoin/js-synchronisation.ts +17 -15
- package/src/families/bitcoin/wallet-btc/crypto/base.ts +33 -21
- package/src/families/bitcoin/wallet-btc/crypto/bip32.ts +36 -0
- package/src/families/bitcoin/wallet-btc/crypto/decred.ts +3 -155
- package/src/families/bitcoin/wallet-btc/storage/index.ts +23 -11
- package/src/families/bitcoin/wallet-btc/storage/types.ts +8 -10
- package/src/families/bitcoin/wallet-btc/xpub.ts +14 -10
- package/src/families/tezos/bridge/js.ts +43 -18
- package/src/families/tezos/signOperation.ts +12 -0
- package/src/families/tezos/synchronisation.ts +1 -1
- package/src/generated/bridge/js.ts +3 -0
- package/src/libcore/buildAccount/index.ts +1 -2
- package/src/mock/account.ts +27 -27
- package/src/types/operation.ts +9 -4
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// from https://github.com/LedgerHQ/xpub-scan/blob/master/src/actions/deriveAddresses.ts
|
|
2
2
|
|
|
3
3
|
import * as bjs from "bitcoinjs-lib";
|
|
4
|
-
import * as bip32 from "bip32";
|
|
5
4
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
5
|
// @ts-ignore
|
|
7
6
|
import { toOutputScript } from "bitcoinjs-lib/src/address";
|
|
8
7
|
import bs58check from "bs58check";
|
|
9
8
|
import { DerivationModes } from "../types";
|
|
10
9
|
import { ICrypto } from "./types";
|
|
10
|
+
import bs58 from "bs58";
|
|
11
|
+
import bech32 from "bech32";
|
|
12
|
+
import BIP32 from "./bip32";
|
|
11
13
|
|
|
12
14
|
export function fallbackValidateAddress(address: string): boolean {
|
|
13
15
|
try {
|
|
@@ -41,7 +43,18 @@ class Base implements ICrypto {
|
|
|
41
43
|
|
|
42
44
|
protected getPubkeyAt(xpub: string, account: number, index: number): Buffer {
|
|
43
45
|
if (!Base.bech32Cache[xpub]) {
|
|
44
|
-
|
|
46
|
+
const buffer: Buffer = bs58.decode(xpub);
|
|
47
|
+
const depth: number = buffer[4];
|
|
48
|
+
const i: number = buffer.readUInt32BE(9);
|
|
49
|
+
const chainCode: Buffer = buffer.slice(13, 45);
|
|
50
|
+
const publicKey: Buffer = buffer.slice(45, 78);
|
|
51
|
+
Base.bech32Cache[xpub] = new BIP32(
|
|
52
|
+
publicKey,
|
|
53
|
+
chainCode,
|
|
54
|
+
this.network,
|
|
55
|
+
depth,
|
|
56
|
+
i
|
|
57
|
+
);
|
|
45
58
|
}
|
|
46
59
|
if (Base.publickeyCache[`${xpub}-${account}-${index}`]) {
|
|
47
60
|
return Base.publickeyCache[`${xpub}-${account}-${index}`];
|
|
@@ -62,33 +75,32 @@ class Base implements ICrypto {
|
|
|
62
75
|
|
|
63
76
|
// derive legacy address at account and index positions
|
|
64
77
|
getLegacyAddress(xpub: string, account: number, index: number): string {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
return String(address);
|
|
78
|
+
const publicKeyBuffer: Buffer = this.getPubkeyAt(xpub, account, index);
|
|
79
|
+
const publicKeyHash160: Buffer = bjs.crypto.hash160(publicKeyBuffer);
|
|
80
|
+
return bjs.address.toBase58Check(publicKeyHash160, this.network.pubKeyHash);
|
|
71
81
|
}
|
|
72
82
|
|
|
73
83
|
// derive native SegWit at account and index positions
|
|
74
84
|
getNativeSegWitAddress(xpub: string, account: number, index: number): string {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return String(address);
|
|
85
|
+
const publicKeyBuffer: Buffer = this.getPubkeyAt(xpub, account, index);
|
|
86
|
+
const publicKeyHash160: Buffer = bjs.crypto.hash160(publicKeyBuffer);
|
|
87
|
+
const words: number[] = bech32.toWords(publicKeyHash160);
|
|
88
|
+
words.unshift(0x00);
|
|
89
|
+
return bech32.encode(this.network.bech32, words);
|
|
81
90
|
}
|
|
82
91
|
|
|
83
92
|
// derive SegWit at account and index positions
|
|
84
93
|
getSegWitAddress(xpub: string, account: number, index: number): string {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
const publicKeyBuffer: Buffer = this.getPubkeyAt(xpub, account, index);
|
|
95
|
+
const redeemOutput: Buffer = bjs.script.compile([
|
|
96
|
+
0,
|
|
97
|
+
bjs.crypto.hash160(publicKeyBuffer),
|
|
98
|
+
]);
|
|
99
|
+
const publicKeyHash160: Buffer = bjs.crypto.hash160(redeemOutput);
|
|
100
|
+
const payload: Buffer = Buffer.allocUnsafe(21);
|
|
101
|
+
payload.writeUInt8(this.network.scriptHash, 0);
|
|
102
|
+
publicKeyHash160.copy(payload, 1);
|
|
103
|
+
return bs58check.encode(payload);
|
|
92
104
|
}
|
|
93
105
|
|
|
94
106
|
// get address given an address type
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import ecc from "tiny-secp256k1";
|
|
2
|
+
import createHmac from "create-hmac";
|
|
3
|
+
|
|
4
|
+
// the BIP32 class is inspired from https://github.com/bitcoinjs/bip32/blob/master/src/bip32.js
|
|
5
|
+
class BIP32 {
|
|
6
|
+
publicKey: any;
|
|
7
|
+
chainCode: any;
|
|
8
|
+
network: any;
|
|
9
|
+
depth: number;
|
|
10
|
+
index: number;
|
|
11
|
+
constructor(
|
|
12
|
+
publicKey: any,
|
|
13
|
+
chainCode: any,
|
|
14
|
+
network: any,
|
|
15
|
+
depth = 0,
|
|
16
|
+
index = 0
|
|
17
|
+
) {
|
|
18
|
+
this.publicKey = publicKey;
|
|
19
|
+
this.chainCode = chainCode;
|
|
20
|
+
this.network = network;
|
|
21
|
+
this.depth = depth;
|
|
22
|
+
this.index = index;
|
|
23
|
+
}
|
|
24
|
+
derive(index: number) {
|
|
25
|
+
const data = Buffer.allocUnsafe(37);
|
|
26
|
+
this.publicKey.copy(data, 0);
|
|
27
|
+
data.writeUInt32BE(index, 33);
|
|
28
|
+
const I = createHmac("sha512", this.chainCode).update(data).digest();
|
|
29
|
+
const IL = I.slice(0, 32);
|
|
30
|
+
const IR = I.slice(32);
|
|
31
|
+
const Ki = ecc.pointAddScalar(this.publicKey, IL, true);
|
|
32
|
+
return new BIP32(Ki, IR, this.network, this.depth + 1, index);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default BIP32;
|
|
@@ -6,150 +6,7 @@ import bs58check from "bs58check";
|
|
|
6
6
|
import createBlakeHash from "blake-hash";
|
|
7
7
|
import RIPEMD160 from "ripemd160";
|
|
8
8
|
import bs58 from "bs58";
|
|
9
|
-
import
|
|
10
|
-
import createHash from "create-hash";
|
|
11
|
-
import createHmac from "create-hmac";
|
|
12
|
-
|
|
13
|
-
// the BIP32 class is inspired from https://github.com/bitcoinjs/bip32/blob/master/src/bip32.js
|
|
14
|
-
class BIP32 {
|
|
15
|
-
privateKey: any;
|
|
16
|
-
publicKey: any;
|
|
17
|
-
chainCode: any;
|
|
18
|
-
network: any;
|
|
19
|
-
depth: number;
|
|
20
|
-
index: number;
|
|
21
|
-
ParentFingerprint: number;
|
|
22
|
-
lowR: boolean;
|
|
23
|
-
constructor(
|
|
24
|
-
privateKey,
|
|
25
|
-
publicKey,
|
|
26
|
-
chainCode,
|
|
27
|
-
network,
|
|
28
|
-
depth = 0,
|
|
29
|
-
index = 0,
|
|
30
|
-
ParentFingerprint = 0x00000000
|
|
31
|
-
) {
|
|
32
|
-
this.privateKey = privateKey;
|
|
33
|
-
this.publicKey = publicKey;
|
|
34
|
-
this.chainCode = chainCode;
|
|
35
|
-
this.network = network;
|
|
36
|
-
this.depth = depth;
|
|
37
|
-
this.index = index;
|
|
38
|
-
this.ParentFingerprint = ParentFingerprint;
|
|
39
|
-
this.lowR = false;
|
|
40
|
-
}
|
|
41
|
-
pk() {
|
|
42
|
-
if (this.publicKey === undefined)
|
|
43
|
-
this.publicKey = ecc.pointFromScalar(this.privateKey, true);
|
|
44
|
-
return this.publicKey;
|
|
45
|
-
}
|
|
46
|
-
isNeutered() {
|
|
47
|
-
return this.privateKey === undefined;
|
|
48
|
-
}
|
|
49
|
-
neutered() {
|
|
50
|
-
return new BIP32(
|
|
51
|
-
undefined,
|
|
52
|
-
this.pk(),
|
|
53
|
-
this.chainCode,
|
|
54
|
-
this.network,
|
|
55
|
-
this.depth,
|
|
56
|
-
this.index,
|
|
57
|
-
this.ParentFingerprint
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
hmacSHA512(key, data) {
|
|
61
|
-
return createHmac("sha512", key).update(data).digest();
|
|
62
|
-
}
|
|
63
|
-
hash160(buffer) {
|
|
64
|
-
const sha256Hash = createHash("sha256").update(buffer).digest();
|
|
65
|
-
return createHash("rmd160").update(sha256Hash).digest();
|
|
66
|
-
}
|
|
67
|
-
fingerprint() {
|
|
68
|
-
return this.hash160(this.pk()).slice(0, 4);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
toBase58() {
|
|
72
|
-
const network = this.network;
|
|
73
|
-
const version = !this.isNeutered()
|
|
74
|
-
? network.bip32.private
|
|
75
|
-
: network.bip32.public;
|
|
76
|
-
const buffer = Buffer.allocUnsafe(78);
|
|
77
|
-
// 4 bytes: version bytes
|
|
78
|
-
buffer.writeUInt32BE(version, 0);
|
|
79
|
-
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ....
|
|
80
|
-
buffer.writeUInt8(this.depth, 4);
|
|
81
|
-
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
|
|
82
|
-
buffer.writeUInt32BE(this.ParentFingerprint, 5);
|
|
83
|
-
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
|
|
84
|
-
// This is encoded in big endian. (0x00000000 if master key)
|
|
85
|
-
buffer.writeUInt32BE(this.index, 9);
|
|
86
|
-
// 32 bytes: the chain code
|
|
87
|
-
this.chainCode.copy(buffer, 13);
|
|
88
|
-
// 33 bytes: the public key or private key data
|
|
89
|
-
if (!this.isNeutered()) {
|
|
90
|
-
// 0x00 + k for private keys
|
|
91
|
-
buffer.writeUInt8(0, 45);
|
|
92
|
-
this.privateKey.copy(buffer, 46);
|
|
93
|
-
// 33 bytes: the public key
|
|
94
|
-
} else {
|
|
95
|
-
// X9.62 encoding for public keys
|
|
96
|
-
this.pk().copy(buffer, 45);
|
|
97
|
-
}
|
|
98
|
-
return bs58check.encode(buffer);
|
|
99
|
-
}
|
|
100
|
-
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
|
|
101
|
-
derive(index) {
|
|
102
|
-
const isHardened = index >= 0x80000000;
|
|
103
|
-
const data = Buffer.allocUnsafe(37);
|
|
104
|
-
// Hardened child
|
|
105
|
-
if (isHardened) {
|
|
106
|
-
data[0] = 0x00;
|
|
107
|
-
this.privateKey.copy(data, 1);
|
|
108
|
-
data.writeUInt32BE(index, 33);
|
|
109
|
-
} else {
|
|
110
|
-
this.pk().copy(data, 0);
|
|
111
|
-
data.writeUInt32BE(index, 33);
|
|
112
|
-
}
|
|
113
|
-
const I = this.hmacSHA512(this.chainCode, data);
|
|
114
|
-
const IL = I.slice(0, 32);
|
|
115
|
-
const IR = I.slice(32);
|
|
116
|
-
// if parse256(IL) >= n, proceed with the next value for i
|
|
117
|
-
if (!ecc.isPrivate(IL)) return this.derive(index + 1);
|
|
118
|
-
// Private parent key -> private child key
|
|
119
|
-
let hd;
|
|
120
|
-
if (!this.isNeutered()) {
|
|
121
|
-
// ki = parse256(IL) + kpar (mod n)
|
|
122
|
-
const ki = ecc.privateAdd(this.privateKey, IL);
|
|
123
|
-
// In case ki == 0, proceed with the next value for i
|
|
124
|
-
if (ki == null) return this.derive(index + 1);
|
|
125
|
-
hd = new BIP32(
|
|
126
|
-
ki,
|
|
127
|
-
undefined,
|
|
128
|
-
IR,
|
|
129
|
-
this.network,
|
|
130
|
-
this.depth + 1,
|
|
131
|
-
index,
|
|
132
|
-
this.fingerprint().readUInt32BE(0)
|
|
133
|
-
);
|
|
134
|
-
} else {
|
|
135
|
-
// Ki = point(parse256(IL)) + Kpar
|
|
136
|
-
// = G*IL + Kpar
|
|
137
|
-
const Ki = ecc.pointAddScalar(this.pk(), IL, true);
|
|
138
|
-
// In case Ki is the point at infinity, proceed with the next value for i
|
|
139
|
-
if (Ki === null) return this.derive(index + 1);
|
|
140
|
-
hd = new BIP32(
|
|
141
|
-
undefined,
|
|
142
|
-
Ki,
|
|
143
|
-
IR,
|
|
144
|
-
this.network,
|
|
145
|
-
this.depth + 1,
|
|
146
|
-
index,
|
|
147
|
-
this.fingerprint().readUInt32BE(0)
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
return hd;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
9
|
+
import BIP32 from "./bip32";
|
|
153
10
|
|
|
154
11
|
class Decred extends Base {
|
|
155
12
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -227,20 +84,11 @@ class Decred extends Base {
|
|
|
227
84
|
buffer = bs58check.decode(xpub);
|
|
228
85
|
}
|
|
229
86
|
const depth = buffer[4];
|
|
230
|
-
const parentFingerprint = buffer.readUInt32BE(5);
|
|
231
87
|
const i = buffer.readUInt32BE(9);
|
|
232
88
|
const chainCode = buffer.slice(13, 45);
|
|
233
89
|
const X = buffer.slice(45, 78);
|
|
234
|
-
const hd = new BIP32(
|
|
235
|
-
|
|
236
|
-
X,
|
|
237
|
-
chainCode,
|
|
238
|
-
this.network,
|
|
239
|
-
depth,
|
|
240
|
-
i,
|
|
241
|
-
parentFingerprint
|
|
242
|
-
);
|
|
243
|
-
const publicKey = hd.derive(account).derive(index).pk();
|
|
90
|
+
const hd = new BIP32(X, chainCode, this.network, depth, i);
|
|
91
|
+
const publicKey = hd.derive(account).derive(index).publicKey;
|
|
244
92
|
const address = Decred.getAddressFromPk(publicKey);
|
|
245
93
|
Base.addressCache[`${derivationMode}-${xpub}-${account}-${index}`] =
|
|
246
94
|
address;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { findLast, filter, uniqBy, findIndex, has } from "lodash";
|
|
2
|
+
import Base from "../crypto/base";
|
|
2
3
|
import { Input, IStorage, Output, TX, Address } from "./types";
|
|
3
4
|
|
|
4
5
|
// a mock storage class that just use js objects
|
|
@@ -12,12 +13,14 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
12
13
|
// accounting
|
|
13
14
|
unspentUtxos: { [key: string]: Output[] } = {};
|
|
14
15
|
|
|
16
|
+
addressCache: { [key: string]: string } = {};
|
|
17
|
+
|
|
15
18
|
// only needed to handle the case when the input
|
|
16
19
|
// is seen before the output (typically explorer
|
|
17
20
|
// returning unordered tx within the same block)
|
|
18
21
|
spentUtxos: { [key: string]: Input[] } = {};
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
getLastTx(txFilter: {
|
|
21
24
|
account?: number;
|
|
22
25
|
index?: number;
|
|
23
26
|
address?: string;
|
|
@@ -38,18 +41,18 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
38
41
|
return tx;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
getTx(address: string, hash: string) {
|
|
42
45
|
const index = `${address}-${hash}`;
|
|
43
46
|
return this.txs[this.primaryIndex[index]];
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
// TODO: only expose unspentUtxos
|
|
47
|
-
|
|
50
|
+
getAddressUnspentUtxos(address: Address) {
|
|
48
51
|
const indexAddress = address.address;
|
|
49
52
|
return this.unspentUtxos[indexAddress];
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
appendTxs(txs: TX[]) {
|
|
53
56
|
const lastLength = this.txs.length;
|
|
54
57
|
|
|
55
58
|
txs.forEach((tx) => {
|
|
@@ -97,10 +100,7 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
97
100
|
return this.txs.length - lastLength;
|
|
98
101
|
}
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
account?: number;
|
|
102
|
-
index?: number;
|
|
103
|
-
}) {
|
|
103
|
+
getUniquesAddresses(addressesFilter: { account?: number; index?: number }) {
|
|
104
104
|
// TODO: to speed up, create more useful indexes in appendTxs
|
|
105
105
|
return uniqBy(
|
|
106
106
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -114,7 +114,7 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
114
114
|
);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
removeTxs(txsFilter: { account: number; index: number }) {
|
|
118
118
|
const newTxs: TX[] = [];
|
|
119
119
|
this.primaryIndex = {};
|
|
120
120
|
|
|
@@ -137,7 +137,7 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
137
137
|
|
|
138
138
|
// We are a bit ugly because we can't rely undo unspentUTXO
|
|
139
139
|
// So we clean the address and rebuild without the pendings
|
|
140
|
-
|
|
140
|
+
removePendingTxs(txsFilter: { account: number; index: number }) {
|
|
141
141
|
const newTxs: TX[] = [];
|
|
142
142
|
const txsToReAdd: TX[] = [];
|
|
143
143
|
this.primaryIndex = {};
|
|
@@ -161,7 +161,14 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
this.txs = newTxs;
|
|
164
|
-
|
|
164
|
+
this.appendTxs(txsToReAdd);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
addAddress(key: string, address: string): void {
|
|
168
|
+
if (!this.addressCache) {
|
|
169
|
+
this.addressCache = {};
|
|
170
|
+
}
|
|
171
|
+
this.addressCache[key] = address;
|
|
165
172
|
}
|
|
166
173
|
|
|
167
174
|
exportSync() {
|
|
@@ -169,6 +176,7 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
169
176
|
txs: this.txs,
|
|
170
177
|
primaryIndex: this.primaryIndex,
|
|
171
178
|
unspentUtxos: this.unspentUtxos,
|
|
179
|
+
addressCache: this.addressCache,
|
|
172
180
|
};
|
|
173
181
|
}
|
|
174
182
|
|
|
@@ -176,10 +184,13 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
176
184
|
txs: TX[];
|
|
177
185
|
primaryIndex: { [key: string]: number };
|
|
178
186
|
unspentUtxos: { [key: string]: Output[] };
|
|
187
|
+
addressCache: { [key: string]: string };
|
|
179
188
|
}) {
|
|
180
189
|
this.txs = data.txs;
|
|
181
190
|
this.primaryIndex = data.primaryIndex;
|
|
182
191
|
this.unspentUtxos = data.unspentUtxos;
|
|
192
|
+
this.addressCache = data.addressCache;
|
|
193
|
+
Base.addressCache = { ...Base.addressCache, ...this.addressCache };
|
|
183
194
|
}
|
|
184
195
|
|
|
185
196
|
async export() {
|
|
@@ -190,6 +201,7 @@ class BitcoinLikeStorage implements IStorage {
|
|
|
190
201
|
txs: TX[];
|
|
191
202
|
primaryIndex: { [key: string]: number };
|
|
192
203
|
unspentUtxos: { [key: string]: Output[] };
|
|
204
|
+
addressCache: { [key: string]: string };
|
|
193
205
|
}) {
|
|
194
206
|
return this.loadSync(data);
|
|
195
207
|
}
|
|
@@ -43,24 +43,22 @@ export interface Address {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export interface IStorage {
|
|
46
|
-
appendTxs(txs: TX[]):
|
|
47
|
-
getAddressUnspentUtxos(address: Address):
|
|
46
|
+
appendTxs(txs: TX[]): number;
|
|
47
|
+
getAddressUnspentUtxos(address: Address): Output[];
|
|
48
48
|
getLastTx(txFilter: {
|
|
49
49
|
account?: number;
|
|
50
50
|
index?: number;
|
|
51
51
|
address?: string;
|
|
52
52
|
confirmed?: boolean;
|
|
53
|
-
}):
|
|
54
|
-
getTx(address: string, hash: string):
|
|
53
|
+
}): TX | undefined;
|
|
54
|
+
getTx(address: string, hash: string): TX | undefined;
|
|
55
55
|
getUniquesAddresses(addressesFilter: {
|
|
56
56
|
account?: number;
|
|
57
57
|
index?: number;
|
|
58
|
-
}):
|
|
59
|
-
removeTxs(txsFilter: { account: number; index: number }):
|
|
60
|
-
removePendingTxs(txsFilter: {
|
|
61
|
-
|
|
62
|
-
index: number;
|
|
63
|
-
}): Promise<void>;
|
|
58
|
+
}): Address[];
|
|
59
|
+
removeTxs(txsFilter: { account: number; index: number }): void;
|
|
60
|
+
removePendingTxs(txsFilter: { account: number; index: number }): void;
|
|
61
|
+
addAddress(key: string, address: string): void;
|
|
64
62
|
export(): Promise<unknown>;
|
|
65
63
|
load(data: unknown): Promise<void>;
|
|
66
64
|
exportSync(): unknown;
|
|
@@ -66,6 +66,10 @@ class Xpub extends EventEmitter {
|
|
|
66
66
|
index
|
|
67
67
|
);
|
|
68
68
|
|
|
69
|
+
this.storage.addAddress(
|
|
70
|
+
`${this.derivationMode}-${this.xpub}-${account}-${index}`,
|
|
71
|
+
address
|
|
72
|
+
);
|
|
69
73
|
await this.whenSynced("address", address);
|
|
70
74
|
|
|
71
75
|
const data = {
|
|
@@ -87,13 +91,13 @@ class Xpub extends EventEmitter {
|
|
|
87
91
|
|
|
88
92
|
// in case pendings have changed we clean them out
|
|
89
93
|
// TODO perf : bad : looping in the tx array
|
|
90
|
-
const hasPendings = !!
|
|
94
|
+
const hasPendings = !!this.storage.getLastTx({
|
|
91
95
|
confirmed: false,
|
|
92
96
|
account,
|
|
93
97
|
index,
|
|
94
|
-
})
|
|
98
|
+
});
|
|
95
99
|
if (hasPendings) {
|
|
96
|
-
|
|
100
|
+
this.storage.removePendingTxs({ account, index });
|
|
97
101
|
}
|
|
98
102
|
total = await this.fetchHydrateAndStoreNewTxs(address, account, index);
|
|
99
103
|
} catch (e) {
|
|
@@ -103,7 +107,7 @@ class Xpub extends EventEmitter {
|
|
|
103
107
|
|
|
104
108
|
this.emitSynced({ ...data, total });
|
|
105
109
|
|
|
106
|
-
const lastTx =
|
|
110
|
+
const lastTx = this.storage.getLastTx({
|
|
107
111
|
account,
|
|
108
112
|
index,
|
|
109
113
|
});
|
|
@@ -200,7 +204,7 @@ class Xpub extends EventEmitter {
|
|
|
200
204
|
async getAddressBalance(address: Address) {
|
|
201
205
|
await this.whenSynced("address", address.address);
|
|
202
206
|
|
|
203
|
-
const unspentUtxos =
|
|
207
|
+
const unspentUtxos = this.storage.getAddressUnspentUtxos(address);
|
|
204
208
|
|
|
205
209
|
return unspentUtxos.reduce(
|
|
206
210
|
(total, { value }) => total.plus(value),
|
|
@@ -419,7 +423,7 @@ class Xpub extends EventEmitter {
|
|
|
419
423
|
let txs: TX[] = [];
|
|
420
424
|
let inserted = 0;
|
|
421
425
|
do {
|
|
422
|
-
const lastTx =
|
|
426
|
+
const lastTx = this.storage.getLastTx({
|
|
423
427
|
account,
|
|
424
428
|
index,
|
|
425
429
|
confirmed: true,
|
|
@@ -433,14 +437,14 @@ class Xpub extends EventEmitter {
|
|
|
433
437
|
if (pendingTxs.length === 0) {
|
|
434
438
|
pendingTxs = txs.filter((tx) => !tx.block);
|
|
435
439
|
}
|
|
436
|
-
inserted +=
|
|
440
|
+
inserted += this.storage.appendTxs(txs.filter((tx) => tx.block)); // only insert not pending tx
|
|
437
441
|
} while (txs.length - pendingTxs.length >= this.txsSyncArraySize); // check whether page is full, if not, it is the last page
|
|
438
|
-
inserted +=
|
|
442
|
+
inserted += this.storage.appendTxs(pendingTxs);
|
|
439
443
|
return inserted;
|
|
440
444
|
}
|
|
441
445
|
|
|
442
446
|
async checkAddressReorg(account: number, index: number) {
|
|
443
|
-
const lastTx =
|
|
447
|
+
const lastTx = this.storage.getLastTx({
|
|
444
448
|
account,
|
|
445
449
|
index,
|
|
446
450
|
confirmed: true,
|
|
@@ -462,7 +466,7 @@ class Xpub extends EventEmitter {
|
|
|
462
466
|
// TODO: delete only everything for this (address, block)
|
|
463
467
|
// but need to think if its possible with current storage implem
|
|
464
468
|
|
|
465
|
-
|
|
469
|
+
this.storage.removeTxs({
|
|
466
470
|
account,
|
|
467
471
|
index,
|
|
468
472
|
});
|
|
@@ -109,7 +109,11 @@ const getTransactionStatus = async (
|
|
|
109
109
|
.lt(thresholdWarning)
|
|
110
110
|
) {
|
|
111
111
|
if (isAccountDelegating(account)) {
|
|
112
|
-
|
|
112
|
+
if (t.useAllAmount) {
|
|
113
|
+
errors.amount = new RecommendUndelegation();
|
|
114
|
+
} else {
|
|
115
|
+
warnings.amount = new RecommendUndelegation();
|
|
116
|
+
}
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
}
|
|
@@ -178,11 +182,14 @@ const prepareTransaction = async (
|
|
|
178
182
|
},
|
|
179
183
|
});
|
|
180
184
|
|
|
185
|
+
const t: Transaction = { ...transaction, taquitoError: null };
|
|
186
|
+
|
|
187
|
+
let amount = transaction.amount;
|
|
181
188
|
if (transaction.useAllAmount) {
|
|
182
189
|
// taquito does not accept 0, so we do 1
|
|
183
190
|
// only failing case is when the account precisely has fees + 1. which is
|
|
184
191
|
// unlikely
|
|
185
|
-
|
|
192
|
+
amount = new BigNumber(1);
|
|
186
193
|
}
|
|
187
194
|
|
|
188
195
|
try {
|
|
@@ -192,7 +199,7 @@ const prepareTransaction = async (
|
|
|
192
199
|
out = await tezos.estimate.transfer({
|
|
193
200
|
mutez: true,
|
|
194
201
|
to: transaction.recipient,
|
|
195
|
-
amount:
|
|
202
|
+
amount: amount.toNumber(),
|
|
196
203
|
});
|
|
197
204
|
break;
|
|
198
205
|
case "delegate":
|
|
@@ -210,7 +217,7 @@ const prepareTransaction = async (
|
|
|
210
217
|
throw new Error("unsupported mode=" + transaction.mode);
|
|
211
218
|
}
|
|
212
219
|
|
|
213
|
-
if (
|
|
220
|
+
if (t.useAllAmount) {
|
|
214
221
|
const totalFees = out.suggestedFeeMutez + out.burnFeeMutez;
|
|
215
222
|
const maxAmount = account.balance
|
|
216
223
|
.minus(totalFees + (tezosResources.revealed ? 0 : DEFAULT_FEE.REVEAL))
|
|
@@ -224,41 +231,59 @@ const prepareTransaction = async (
|
|
|
224
231
|
return gasBuffer * MINIMAL_FEE_PER_GAS_MUTEZ + opSize;
|
|
225
232
|
};
|
|
226
233
|
const incr = increasedFee(gasBuffer, Number(out.opSize));
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
234
|
+
t.fees = new BigNumber(out.suggestedFeeMutez + incr);
|
|
235
|
+
t.gasLimit = new BigNumber(out.gasLimit + gasBuffer);
|
|
236
|
+
t.amount = new BigNumber(maxAmount - incr);
|
|
230
237
|
} else {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
238
|
+
t.fees = new BigNumber(out.suggestedFeeMutez);
|
|
239
|
+
t.gasLimit = new BigNumber(out.gasLimit);
|
|
240
|
+
t.storageLimit = new BigNumber(out.storageLimit);
|
|
234
241
|
}
|
|
235
242
|
|
|
236
|
-
|
|
237
|
-
|
|
243
|
+
t.storageLimit = new BigNumber(out.storageLimit);
|
|
244
|
+
t.estimatedFees = t.fees;
|
|
238
245
|
if (!tezosResources.revealed) {
|
|
239
|
-
|
|
240
|
-
DEFAULT_FEE.REVEAL
|
|
241
|
-
);
|
|
246
|
+
t.estimatedFees = t.estimatedFees.plus(DEFAULT_FEE.REVEAL);
|
|
242
247
|
}
|
|
243
248
|
} catch (e) {
|
|
244
249
|
if (typeof e !== "object" || !e) throw e;
|
|
245
250
|
if ("id" in e) {
|
|
246
|
-
|
|
251
|
+
t.taquitoError = (e as { id: string }).id;
|
|
247
252
|
} else if ("status" in e) {
|
|
248
253
|
// in case of http 400, log & ignore (more case to handle)
|
|
249
254
|
log(
|
|
250
255
|
"taquito-network-error",
|
|
251
256
|
String((e as { message: string }).message || ""),
|
|
252
|
-
{ transaction }
|
|
257
|
+
{ transaction: t }
|
|
253
258
|
);
|
|
254
259
|
} else {
|
|
255
260
|
throw e;
|
|
256
261
|
}
|
|
257
262
|
}
|
|
258
263
|
|
|
259
|
-
|
|
264
|
+
// nothing changed
|
|
265
|
+
if (
|
|
266
|
+
bnEq(t.fees, transaction.fees) &&
|
|
267
|
+
bnEq(t.fees, transaction.fees) &&
|
|
268
|
+
bnEq(t.gasLimit, transaction.gasLimit) &&
|
|
269
|
+
bnEq(t.amount, transaction.amount) &&
|
|
270
|
+
bnEq(t.storageLimit, transaction.storageLimit) &&
|
|
271
|
+
bnEq(t.estimatedFees, transaction.estimatedFees) &&
|
|
272
|
+
t.taquitoError === transaction.taquitoError
|
|
273
|
+
) {
|
|
274
|
+
return transaction;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return t;
|
|
260
278
|
};
|
|
261
279
|
|
|
280
|
+
function bnEq(
|
|
281
|
+
a: BigNumber | null | undefined,
|
|
282
|
+
b: BigNumber | null | undefined
|
|
283
|
+
): boolean {
|
|
284
|
+
return !a && !b ? true : !a || !b ? false : a.eq(b);
|
|
285
|
+
}
|
|
286
|
+
|
|
262
287
|
const estimateMaxSpendable = async ({
|
|
263
288
|
account,
|
|
264
289
|
parentAccount,
|
|
@@ -8,6 +8,8 @@ import type { Account, SignOperationEvent } from "../../types";
|
|
|
8
8
|
import { withDevice } from "../../hw/deviceAccess";
|
|
9
9
|
import { getEnv } from "../../env";
|
|
10
10
|
import { FeeNotLoaded } from "@ledgerhq/errors";
|
|
11
|
+
import { upperModulo } from "../../modulo";
|
|
12
|
+
import BigNumber from "bignumber.js";
|
|
11
13
|
|
|
12
14
|
export const signOperation = ({
|
|
13
15
|
account,
|
|
@@ -53,6 +55,16 @@ export const signOperation = ({
|
|
|
53
55
|
storageLimit: transaction.storageLimit?.toNumber() || 0,
|
|
54
56
|
gasLimit: transaction.gasLimit?.toNumber() || 0,
|
|
55
57
|
};
|
|
58
|
+
|
|
59
|
+
if (["delegate", "undelegate"].includes(transaction.mode)) {
|
|
60
|
+
// https://ledgerhq.atlassian.net/browse/LL-8821
|
|
61
|
+
params.gasLimit = upperModulo(
|
|
62
|
+
transaction.gasLimit || new BigNumber(0),
|
|
63
|
+
new BigNumber(136),
|
|
64
|
+
new BigNumber(1000)
|
|
65
|
+
).toNumber();
|
|
66
|
+
}
|
|
67
|
+
|
|
56
68
|
switch (transaction.mode) {
|
|
57
69
|
case "send":
|
|
58
70
|
res = await tezos.contract.transfer({
|