forked from LedgerHQ/ledger-live-desktop
/
proxy.js
130 lines (114 loc) · 3.91 KB
/
proxy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* eslint-disable flowtype/generic-spacing */
// @flow
import { BigNumber } from "bignumber.js";
import { map } from "rxjs/operators";
import type {
CryptoCurrency,
Account,
AccountLike,
CurrencyBridge,
AccountBridge,
} from "@ledgerhq/live-common/lib/types";
import isEqual from "lodash/isEqual";
import {
fromTransactionRaw,
toTransactionRaw,
toSignedOperationRaw,
fromTransactionStatusRaw,
fromSignOperationEventRaw,
} from "@ledgerhq/live-common/lib/transaction";
import {
toAccountLikeRaw,
toAccountRaw,
fromOperationRaw,
} from "@ledgerhq/live-common/lib/account";
import { patchAccount } from "@ledgerhq/live-common/lib/reconciliation";
import { fromScanAccountEventRaw } from "@ledgerhq/live-common/lib/bridge";
import * as bridgeImpl from "@ledgerhq/live-common/lib/bridge/impl";
import { command } from "~/renderer/commands";
const scanAccounts = ({ currency, deviceId, syncConfig }) =>
command("CurrencyScanAccounts")({
currencyId: currency.id,
deviceId,
syncConfig,
}).pipe(map(fromScanAccountEventRaw));
export const getCurrencyBridge = (currency: CryptoCurrency): CurrencyBridge => ({
preload: async () => {
const value = await command("CurrencyPreload")({ currencyId: currency.id }).toPromise();
bridgeImpl.getCurrencyBridge(currency).hydrate(value);
return value;
},
hydrate: value => bridgeImpl.getCurrencyBridge(currency).hydrate(value),
scanAccounts,
});
export const getAccountBridge = (
account: AccountLike,
parentAccount: ?Account,
): AccountBridge<any> => {
const sync = (account, syncConfig) =>
command("AccountSync")({
account: toAccountRaw(account),
syncConfig,
}).pipe(map(raw => account => patchAccount(account, raw)));
const receive = (account, arg) =>
command("AccountReceive")({
account: toAccountRaw(account),
arg,
});
const createTransaction = a =>
bridgeImpl.getAccountBridge(account, parentAccount).createTransaction(a);
const updateTransaction = (a, patch) =>
bridgeImpl.getAccountBridge(account, parentAccount).updateTransaction(a, patch);
const prepareTransaction = async (a, t) => {
const transaction = toTransactionRaw(t);
const result = await command("AccountPrepareTransaction")({
account: toAccountRaw(a),
transaction,
}).toPromise();
// this will remove the `undefined` fields due to JSON back&forth
const sentTransaction = JSON.parse(JSON.stringify(transaction));
if (isEqual(sentTransaction, result)) {
return t; // preserve reference by deep equality of the TransactionRaw
}
return fromTransactionRaw(result);
};
const getTransactionStatus = (a, t) =>
command("AccountGetTransactionStatus")({
account: toAccountRaw(a),
transaction: toTransactionRaw(t),
})
.toPromise()
.then(fromTransactionStatusRaw);
const signOperation = ({ account, transaction, deviceId }) =>
command("AccountSignOperation")({
account: toAccountRaw(account),
transaction: toTransactionRaw(transaction),
deviceId,
}).pipe(map(raw => fromSignOperationEventRaw(raw, account.id)));
const broadcast = ({ account, signedOperation }) =>
command("AccountBroadcast")({
account: toAccountRaw(account),
signedOperation: toSignedOperationRaw(signedOperation, true),
})
.pipe(map(raw => fromOperationRaw(raw, account.id)))
.toPromise();
const estimateMaxSpendable = ({ account, parentAccount, transaction }) =>
command("AccountEstimateMaxSpendable")({
account: toAccountLikeRaw(account),
parentAccount: parentAccount ? toAccountRaw(parentAccount) : null,
transaction: transaction ? toTransactionRaw(transaction) : null,
})
.pipe(map(raw => BigNumber(raw)))
.toPromise();
return {
createTransaction,
updateTransaction,
getTransactionStatus,
prepareTransaction,
sync,
receive,
signOperation,
broadcast,
estimateMaxSpendable,
};
};