@ledgerhq/live-common 21.23.0 → 21.24.0-beta.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/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/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/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/env.d.ts +10 -5
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +5 -0
- 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/bitcoin/js-synchronisation.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.js +10 -12
- 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 -114
- 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/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/package.json +3 -3
- package/src/data/icons/react/index.tsx +1 -0
- package/src/data/icons/react/ssv.tsx +12 -0
- package/src/data/icons/reactNative/index.tsx +1 -0
- package/src/data/icons/reactNative/ssv.tsx +13 -0
- package/src/data/icons/svg/SSV.svg +4 -0
- package/src/env.ts +5 -0
- package/src/families/bitcoin/js-synchronisation.ts +14 -13
- 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 -154
- 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/signOperation.ts +12 -0
- package/src/families/tezos/synchronisation.ts +1 -1
|
@@ -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,149 +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
|
-
hashSHA256(buffer) {
|
|
64
|
-
return createHash("sha256").update(buffer).digest();
|
|
65
|
-
}
|
|
66
|
-
fingerprint() {
|
|
67
|
-
return this.hashSHA256(this.pk()).slice(0, 4);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
toBase58() {
|
|
71
|
-
const network = this.network;
|
|
72
|
-
const version = !this.isNeutered()
|
|
73
|
-
? network.bip32.private
|
|
74
|
-
: network.bip32.public;
|
|
75
|
-
const buffer = Buffer.allocUnsafe(78);
|
|
76
|
-
// 4 bytes: version bytes
|
|
77
|
-
buffer.writeUInt32BE(version, 0);
|
|
78
|
-
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ....
|
|
79
|
-
buffer.writeUInt8(this.depth, 4);
|
|
80
|
-
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
|
|
81
|
-
buffer.writeUInt32BE(this.ParentFingerprint, 5);
|
|
82
|
-
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
|
|
83
|
-
// This is encoded in big endian. (0x00000000 if master key)
|
|
84
|
-
buffer.writeUInt32BE(this.index, 9);
|
|
85
|
-
// 32 bytes: the chain code
|
|
86
|
-
this.chainCode.copy(buffer, 13);
|
|
87
|
-
// 33 bytes: the public key or private key data
|
|
88
|
-
if (!this.isNeutered()) {
|
|
89
|
-
// 0x00 + k for private keys
|
|
90
|
-
buffer.writeUInt8(0, 45);
|
|
91
|
-
this.privateKey.copy(buffer, 46);
|
|
92
|
-
// 33 bytes: the public key
|
|
93
|
-
} else {
|
|
94
|
-
// X9.62 encoding for public keys
|
|
95
|
-
this.pk().copy(buffer, 45);
|
|
96
|
-
}
|
|
97
|
-
return bs58check.encode(buffer);
|
|
98
|
-
}
|
|
99
|
-
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
|
|
100
|
-
derive(index) {
|
|
101
|
-
const isHardened = index >= 0x80000000;
|
|
102
|
-
const data = Buffer.allocUnsafe(37);
|
|
103
|
-
// Hardened child
|
|
104
|
-
if (isHardened) {
|
|
105
|
-
data[0] = 0x00;
|
|
106
|
-
this.privateKey.copy(data, 1);
|
|
107
|
-
data.writeUInt32BE(index, 33);
|
|
108
|
-
} else {
|
|
109
|
-
this.pk().copy(data, 0);
|
|
110
|
-
data.writeUInt32BE(index, 33);
|
|
111
|
-
}
|
|
112
|
-
const I = this.hmacSHA512(this.chainCode, data);
|
|
113
|
-
const IL = I.slice(0, 32);
|
|
114
|
-
const IR = I.slice(32);
|
|
115
|
-
// if parse256(IL) >= n, proceed with the next value for i
|
|
116
|
-
if (!ecc.isPrivate(IL)) return this.derive(index + 1);
|
|
117
|
-
// Private parent key -> private child key
|
|
118
|
-
let hd;
|
|
119
|
-
if (!this.isNeutered()) {
|
|
120
|
-
// ki = parse256(IL) + kpar (mod n)
|
|
121
|
-
const ki = ecc.privateAdd(this.privateKey, IL);
|
|
122
|
-
// In case ki == 0, proceed with the next value for i
|
|
123
|
-
if (ki == null) return this.derive(index + 1);
|
|
124
|
-
hd = new BIP32(
|
|
125
|
-
ki,
|
|
126
|
-
undefined,
|
|
127
|
-
IR,
|
|
128
|
-
this.network,
|
|
129
|
-
this.depth + 1,
|
|
130
|
-
index,
|
|
131
|
-
this.fingerprint().readUInt32BE(0)
|
|
132
|
-
);
|
|
133
|
-
} else {
|
|
134
|
-
// Ki = point(parse256(IL)) + Kpar
|
|
135
|
-
// = G*IL + Kpar
|
|
136
|
-
const Ki = ecc.pointAddScalar(this.pk(), IL, true);
|
|
137
|
-
// In case Ki is the point at infinity, proceed with the next value for i
|
|
138
|
-
if (Ki === null) return this.derive(index + 1);
|
|
139
|
-
hd = new BIP32(
|
|
140
|
-
undefined,
|
|
141
|
-
Ki,
|
|
142
|
-
IR,
|
|
143
|
-
this.network,
|
|
144
|
-
this.depth + 1,
|
|
145
|
-
index,
|
|
146
|
-
this.fingerprint().readUInt32BE(0)
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
return hd;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
9
|
+
import BIP32 from "./bip32";
|
|
152
10
|
|
|
153
11
|
class Decred extends Base {
|
|
154
12
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -226,20 +84,11 @@ class Decred extends Base {
|
|
|
226
84
|
buffer = bs58check.decode(xpub);
|
|
227
85
|
}
|
|
228
86
|
const depth = buffer[4];
|
|
229
|
-
const parentFingerprint = buffer.readUInt32BE(5);
|
|
230
87
|
const i = buffer.readUInt32BE(9);
|
|
231
88
|
const chainCode = buffer.slice(13, 45);
|
|
232
89
|
const X = buffer.slice(45, 78);
|
|
233
|
-
const hd = new BIP32(
|
|
234
|
-
|
|
235
|
-
X,
|
|
236
|
-
chainCode,
|
|
237
|
-
this.network,
|
|
238
|
-
depth,
|
|
239
|
-
i,
|
|
240
|
-
parentFingerprint
|
|
241
|
-
);
|
|
242
|
-
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;
|
|
243
92
|
const address = Decred.getAddressFromPk(publicKey);
|
|
244
93
|
Base.addressCache[`${derivationMode}-${xpub}-${account}-${index}`] =
|
|
245
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
|
});
|
|
@@ -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({
|