@ledgerhq/live-common 24.1.0 → 25.0.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/apps/support.js +1 -1
- package/lib/apps/support.js.map +1 -1
- package/lib/bot/index.d.ts.map +1 -1
- package/lib/bot/index.js +4 -2
- package/lib/bot/index.js.map +1 -1
- package/lib/bot/specs.d.ts +1 -0
- package/lib/bot/specs.d.ts.map +1 -1
- package/lib/bot/specs.js +6 -1
- package/lib/bot/specs.js.map +1 -1
- package/lib/currencies/support.d.ts +1 -1
- package/lib/currencies/support.d.ts.map +1 -1
- package/lib/env.d.ts +15 -5
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +10 -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/errors.d.ts +101 -306
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +3 -4
- package/lib/errors.js.map +1 -1
- package/lib/errors.test.d.ts +2 -0
- package/lib/errors.test.d.ts.map +1 -0
- package/lib/errors.test.js +20 -0
- package/lib/errors.test.js.map +1 -0
- package/lib/exchange/swap/utils/index.test.js +2 -2
- package/lib/exchange/swap/utils/index.test.js.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin.js +2 -4
- package/lib/families/bitcoin/datasets/bitcoin.js.map +1 -1
- package/lib/families/bitcoin/descriptor.d.ts.map +1 -1
- package/lib/families/bitcoin/descriptor.js +3 -1
- package/lib/families/bitcoin/descriptor.js.map +1 -1
- package/lib/families/bitcoin/errors.d.ts +1 -3
- package/lib/families/bitcoin/errors.d.ts.map +1 -1
- package/lib/families/bitcoin/exchange.js +1 -1
- package/lib/families/bitcoin/exchange.js.map +1 -1
- package/lib/families/bitcoin/hw-getAddress.d.ts +1 -1
- package/lib/families/bitcoin/hw-getAddress.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.js +20 -2
- package/lib/families/bitcoin/js-synchronisation.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/index.d.ts +0 -36
- package/lib/families/bitcoin/wallet-btc/storage/index.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/index.js +14 -14
- package/lib/families/bitcoin/wallet-btc/storage/index.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/storage/types.d.ts +1 -0
- package/lib/families/bitcoin/wallet-btc/storage/types.d.ts.map +1 -1
- package/lib/families/bitcoin/xpub.txs.loadExport.unit.test.d.ts +2 -0
- package/lib/families/bitcoin/xpub.txs.loadExport.unit.test.d.ts.map +1 -0
- package/lib/families/bitcoin/xpub.txs.loadExport.unit.test.js +146 -0
- package/lib/families/bitcoin/xpub.txs.loadExport.unit.test.js.map +1 -0
- package/lib/families/cardano/errors.d.ts +1 -3
- package/lib/families/cardano/errors.d.ts.map +1 -1
- package/lib/families/crypto_org/errors.d.ts +3 -9
- package/lib/families/crypto_org/errors.d.ts.map +1 -1
- package/lib/families/ethereum/exchange.js +1 -1
- package/lib/families/ethereum/exchange.js.map +1 -1
- package/lib/families/ethereum/modules/index.d.ts +1 -1
- package/lib/families/ethereum/modules/index.d.ts.map +1 -1
- package/lib/families/ethereum/signOperation.js +2 -2
- package/lib/families/ethereum/signOperation.js.map +1 -1
- package/lib/families/ethereum/specs.d.ts +1 -1
- package/lib/families/ethereum/specs.js +5 -5
- package/lib/families/ethereum/specs.js.map +1 -1
- package/lib/families/polkadot/errors.d.ts +12 -36
- package/lib/families/polkadot/errors.d.ts.map +1 -1
- package/lib/families/ripple/exchange.js +1 -1
- package/lib/families/ripple/exchange.js.map +1 -1
- package/lib/families/solana/api/chain/instruction/token/types.d.ts +3 -3
- package/lib/families/solana/errors.d.ts +20 -60
- package/lib/families/solana/errors.d.ts.map +1 -1
- package/lib/families/stellar/api/horizon.d.ts +29 -7
- package/lib/families/stellar/api/horizon.d.ts.map +1 -1
- package/lib/families/stellar/api/horizon.js +114 -58
- package/lib/families/stellar/api/horizon.js.map +1 -1
- package/lib/families/stellar/api/index.d.ts +1 -1
- package/lib/families/stellar/api/index.d.ts.map +1 -1
- package/lib/families/stellar/api/index.js +5 -1
- package/lib/families/stellar/api/index.js.map +1 -1
- package/lib/families/stellar/bridge/mock.d.ts.map +1 -1
- package/lib/families/stellar/bridge/mock.js +4 -1
- package/lib/families/stellar/bridge/mock.js.map +1 -1
- package/lib/families/stellar/bridge.integration.test.js +12 -4
- package/lib/families/stellar/bridge.integration.test.js.map +1 -1
- package/lib/families/stellar/cli-transaction.d.ts +3 -1
- package/lib/families/stellar/cli-transaction.d.ts.map +1 -1
- package/lib/families/stellar/cli-transaction.js +48 -2
- package/lib/families/stellar/cli-transaction.js.map +1 -1
- package/lib/families/stellar/deviceTransactionConfig.d.ts +7 -1
- package/lib/families/stellar/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/families/stellar/deviceTransactionConfig.js +12 -1
- package/lib/families/stellar/deviceTransactionConfig.js.map +1 -1
- package/lib/families/stellar/errors.d.ts +12 -0
- package/lib/families/stellar/errors.d.ts.map +1 -0
- package/lib/families/stellar/errors.js +16 -0
- package/lib/families/stellar/errors.js.map +1 -0
- package/lib/families/stellar/exchange.js +1 -1
- package/lib/families/stellar/exchange.js.map +1 -1
- package/lib/families/stellar/js-buildTransaction.d.ts.map +1 -1
- package/lib/families/stellar/js-buildTransaction.js +34 -16
- package/lib/families/stellar/js-buildTransaction.js.map +1 -1
- package/lib/families/stellar/js-createTransaction.d.ts.map +1 -1
- package/lib/families/stellar/js-createTransaction.js +4 -1
- package/lib/families/stellar/js-createTransaction.js.map +1 -1
- package/lib/families/stellar/js-estimateMaxSpendable.js +2 -1
- package/lib/families/stellar/js-estimateMaxSpendable.js.map +1 -1
- package/lib/families/stellar/js-getTransactionStatus.d.ts.map +1 -1
- package/lib/families/stellar/js-getTransactionStatus.js +127 -57
- package/lib/families/stellar/js-getTransactionStatus.js.map +1 -1
- package/lib/families/stellar/js-prepareTransaction.d.ts.map +1 -1
- package/lib/families/stellar/js-prepareTransaction.js +25 -7
- package/lib/families/stellar/js-prepareTransaction.js.map +1 -1
- package/lib/families/stellar/js-signOperation.d.ts.map +1 -1
- package/lib/families/stellar/js-signOperation.js +33 -6
- package/lib/families/stellar/js-signOperation.js.map +1 -1
- package/lib/families/stellar/js-synchronization.d.ts +1 -1
- package/lib/families/stellar/js-synchronization.d.ts.map +1 -1
- package/lib/families/stellar/js-synchronization.js +42 -16
- package/lib/families/stellar/js-synchronization.js.map +1 -1
- package/lib/families/stellar/logic.d.ts +21 -14
- package/lib/families/stellar/logic.d.ts.map +1 -1
- package/lib/families/stellar/logic.js +158 -57
- package/lib/families/stellar/logic.js.map +1 -1
- package/lib/families/stellar/specs.d.ts.map +1 -1
- package/lib/families/stellar/specs.js +182 -7
- package/lib/families/stellar/specs.js.map +1 -1
- package/lib/families/stellar/speculos-deviceActions.d.ts.map +1 -1
- package/lib/families/stellar/speculos-deviceActions.js +60 -28
- package/lib/families/stellar/speculos-deviceActions.js.map +1 -1
- package/lib/families/stellar/tokens.d.ts +11 -0
- package/lib/families/stellar/tokens.d.ts.map +1 -0
- package/lib/families/stellar/tokens.js +82 -0
- package/lib/families/stellar/tokens.js.map +1 -0
- package/lib/families/stellar/transaction.d.ts +2 -2
- package/lib/families/stellar/transaction.d.ts.map +1 -1
- package/lib/families/stellar/transaction.js +32 -6
- package/lib/families/stellar/transaction.js.map +1 -1
- package/lib/families/stellar/types.d.ts +45 -0
- package/lib/families/stellar/types.d.ts.map +1 -1
- package/lib/families/stellar/types.js +7 -1
- package/lib/families/stellar/types.js.map +1 -1
- package/lib/families/tezos/exchange.js +1 -1
- package/lib/families/tezos/exchange.js.map +1 -1
- package/lib/generated/cli-transaction.d.ts +1 -0
- package/lib/generated/cli-transaction.d.ts.map +1 -1
- package/lib/generated/specs.d.ts +1 -1
- package/lib/generated/transaction.d.ts +1 -1
- package/lib/hw/signMessage/index.d.ts +4 -3
- package/lib/hw/signMessage/index.d.ts.map +1 -1
- package/lib/hw/signMessage/index.js +25 -11
- package/lib/hw/signMessage/index.js.map +1 -1
- package/lib/hw/signMessage/index.test.d.ts +2 -0
- package/lib/hw/signMessage/index.test.d.ts.map +1 -0
- package/lib/hw/signMessage/index.test.js +126 -0
- package/lib/hw/signMessage/index.test.js.map +1 -0
- package/lib/load/speculos.d.ts.map +1 -1
- package/lib/load/speculos.js +1 -3
- package/lib/load/speculos.js.map +1 -1
- package/lib/mock/Btc.d.ts +1 -1
- package/lib/mock/Btc.d.ts.map +1 -1
- package/lib/performance.d.ts +10 -0
- package/lib/performance.d.ts.map +1 -0
- package/lib/performance.js +72 -0
- package/lib/performance.js.map +1 -0
- package/lib/performance.test.d.ts +2 -0
- package/lib/performance.test.d.ts.map +1 -0
- package/lib/performance.test.js +28 -0
- package/lib/performance.test.js.map +1 -0
- package/lib/platform/providers/RemoteLiveAppProvider/api/index.d.ts.map +1 -1
- package/lib/platform/providers/RemoteLiveAppProvider/api/index.js +28 -0
- package/lib/platform/providers/RemoteLiveAppProvider/api/index.js.map +1 -1
- package/lib/platform/providers/RemoteLiveAppProvider/api/mock.json +0 -31
- package/lib/types/currencies.d.ts +1 -1
- package/lib/types/currencies.d.ts.map +1 -1
- package/lib/walletconnect/Provider.d.ts.map +1 -1
- package/lib/walletconnect/Provider.js +1 -3
- package/lib/walletconnect/Provider.js.map +1 -1
- package/package.json +71 -19
- package/src/apps/support.ts +1 -1
- package/src/bot/index.ts +3 -1
- package/src/bot/specs.ts +7 -1
- package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +34 -6
- package/src/currencies/support.ts +1 -1
- package/src/env.ts +10 -0
- package/src/errors.test.ts +21 -0
- package/src/errors.ts +1 -6
- package/src/exchange/swap/utils/index.test.ts +1 -1
- package/src/families/bitcoin/datasets/bitcoin.ts +0 -2
- package/src/families/bitcoin/descriptor.ts +4 -1
- package/src/families/bitcoin/exchange.ts +1 -1
- package/src/families/bitcoin/hw-getAddress.ts +1 -1
- package/src/families/bitcoin/js-synchronisation.ts +23 -1
- package/src/families/bitcoin/wallet-btc/storage/index.ts +17 -31
- package/src/families/bitcoin/wallet-btc/storage/types.ts +1 -0
- package/src/families/bitcoin/wallet-btc/wallet.ts +1 -1
- package/src/families/bitcoin/xpub.txs.loadExport.unit.test.ts +101 -0
- package/src/families/ethereum/exchange.ts +1 -1
- package/src/families/ethereum/modules/index.ts +1 -1
- package/src/families/ethereum/signOperation.ts +2 -2
- package/src/families/ethereum/specs.ts +5 -5
- package/src/families/ripple/exchange.ts +1 -1
- package/src/families/stellar/__snapshots__/bridge.integration.test.ts.snap +765 -339
- package/src/families/stellar/api/horizon.ts +115 -33
- package/src/families/stellar/api/index.ts +4 -0
- package/src/families/stellar/bridge/mock.ts +3 -0
- package/src/families/stellar/bridge.integration.test.ts +10 -2
- package/src/families/stellar/cli-transaction.ts +75 -2
- package/src/families/stellar/deviceTransactionConfig.ts +22 -0
- package/src/families/stellar/errors.ts +34 -0
- package/src/families/stellar/exchange.ts +1 -1
- package/src/families/stellar/js-buildTransaction.ts +56 -16
- package/src/families/stellar/js-createTransaction.ts +3 -0
- package/src/families/stellar/js-estimateMaxSpendable.ts +1 -1
- package/src/families/stellar/js-getTransactionStatus.ts +152 -60
- package/src/families/stellar/js-prepareTransaction.ts +4 -3
- package/src/families/stellar/js-signOperation.ts +37 -6
- package/src/families/stellar/js-synchronization.ts +53 -11
- package/src/families/stellar/logic.ts +198 -62
- package/src/families/stellar/specs.ts +227 -8
- package/src/families/stellar/speculos-deviceActions.ts +66 -22
- package/src/families/stellar/tokens.ts +118 -0
- package/src/families/stellar/transaction.ts +31 -3
- package/src/families/stellar/types.ts +52 -0
- package/src/families/tezos/exchange.ts +1 -1
- package/src/hw/signMessage/index.test.ts +128 -0
- package/src/hw/signMessage/index.ts +37 -15
- package/src/load/speculos.ts +1 -3
- package/src/mock/Btc.ts +1 -1
- package/src/performance.test.ts +26 -0
- package/src/performance.ts +61 -0
- package/src/platform/providers/RemoteLiveAppProvider/api/index.ts +6 -0
- package/src/platform/providers/RemoteLiveAppProvider/api/mock.json +1 -32
- package/src/types/currencies.ts +1 -1
- package/src/walletconnect/Provider.tsx +4 -5
|
@@ -12,15 +12,25 @@ import type { NetworkInfo } from "../types";
|
|
|
12
12
|
import {
|
|
13
13
|
getAccountSpendableBalance,
|
|
14
14
|
rawOperationsToOperations,
|
|
15
|
+
getReservedBalance,
|
|
15
16
|
} from "../logic";
|
|
16
17
|
import { NetworkDown, LedgerAPI4xx, LedgerAPI5xx } from "@ledgerhq/errors";
|
|
17
18
|
import { requestInterceptor, responseInterceptor } from "../../../network";
|
|
19
|
+
import type { BalanceAsset } from "../types";
|
|
20
|
+
import { NetworkCongestionLevel, Signer } from "../types";
|
|
18
21
|
|
|
19
22
|
const LIMIT = getEnv("API_STELLAR_HORIZON_FETCH_LIMIT");
|
|
20
23
|
const FALLBACK_BASE_FEE = 100;
|
|
24
|
+
const TRESHOLD_LOW = 0.5;
|
|
25
|
+
const TRESHOLD_MEDIUM = 0.75;
|
|
21
26
|
const currency = getCryptoCurrencyById("stellar");
|
|
22
27
|
const server = new StellarSdk.Server(getEnv("API_STELLAR_HORIZON"));
|
|
23
28
|
|
|
29
|
+
// Constants
|
|
30
|
+
export const BASE_RESERVE = 0.5;
|
|
31
|
+
export const BASE_RESERVE_MIN_COUNT = 2;
|
|
32
|
+
export const MIN_BALANCE = 1;
|
|
33
|
+
|
|
24
34
|
StellarSdk.HorizonAxiosClient.interceptors.request.use(requestInterceptor);
|
|
25
35
|
|
|
26
36
|
StellarSdk.HorizonAxiosClient.interceptors.response.use((response) => {
|
|
@@ -46,16 +56,48 @@ const getFormattedAmount = (amount: BigNumber) => {
|
|
|
46
56
|
.toString(10);
|
|
47
57
|
};
|
|
48
58
|
|
|
49
|
-
export const fetchBaseFee = async (): Promise<
|
|
50
|
-
|
|
59
|
+
export const fetchBaseFee = async (): Promise<{
|
|
60
|
+
baseFee: number;
|
|
61
|
+
recommendedFee: number;
|
|
62
|
+
networkCongestionLevel: NetworkCongestionLevel;
|
|
63
|
+
}> => {
|
|
64
|
+
// For tests
|
|
65
|
+
if (getEnv("API_STELLAR_HORIZON_STATIC_FEE")) {
|
|
66
|
+
return {
|
|
67
|
+
baseFee: 100,
|
|
68
|
+
recommendedFee: 100,
|
|
69
|
+
networkCongestionLevel: NetworkCongestionLevel.LOW,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const baseFee = StellarSdk.BASE_FEE || FALLBACK_BASE_FEE;
|
|
74
|
+
let recommendedFee = baseFee;
|
|
75
|
+
let networkCongestionLevel = NetworkCongestionLevel.MEDIUM;
|
|
51
76
|
|
|
52
77
|
try {
|
|
53
|
-
|
|
78
|
+
const feeStats = await server.feeStats();
|
|
79
|
+
const ledgerCapacityUsage = feeStats.ledger_capacity_usage;
|
|
80
|
+
recommendedFee = Number(feeStats.fee_charged.mode);
|
|
81
|
+
|
|
82
|
+
if (
|
|
83
|
+
ledgerCapacityUsage > TRESHOLD_LOW &&
|
|
84
|
+
ledgerCapacityUsage <= TRESHOLD_MEDIUM
|
|
85
|
+
) {
|
|
86
|
+
networkCongestionLevel = NetworkCongestionLevel.MEDIUM;
|
|
87
|
+
} else if (ledgerCapacityUsage > TRESHOLD_MEDIUM) {
|
|
88
|
+
networkCongestionLevel = NetworkCongestionLevel.HIGH;
|
|
89
|
+
} else {
|
|
90
|
+
networkCongestionLevel = NetworkCongestionLevel.LOW;
|
|
91
|
+
}
|
|
54
92
|
} catch (e) {
|
|
55
|
-
|
|
93
|
+
// do nothing, will use defaults
|
|
56
94
|
}
|
|
57
95
|
|
|
58
|
-
return
|
|
96
|
+
return {
|
|
97
|
+
baseFee,
|
|
98
|
+
recommendedFee,
|
|
99
|
+
networkCongestionLevel,
|
|
100
|
+
};
|
|
59
101
|
};
|
|
60
102
|
|
|
61
103
|
/**
|
|
@@ -70,15 +112,21 @@ export const fetchAccount = async (
|
|
|
70
112
|
blockHeight?: number;
|
|
71
113
|
balance: BigNumber;
|
|
72
114
|
spendableBalance: BigNumber;
|
|
115
|
+
assets: BalanceAsset[];
|
|
73
116
|
}> => {
|
|
74
117
|
let account: typeof AccountRecord = {};
|
|
75
118
|
let balance: Record<string, any> = {};
|
|
119
|
+
let assets: BalanceAsset[] = [];
|
|
76
120
|
|
|
77
121
|
try {
|
|
78
122
|
account = await server.accounts().accountId(addr).call();
|
|
79
|
-
balance = account.balances
|
|
123
|
+
balance = account.balances?.find((balance) => {
|
|
80
124
|
return balance.asset_type === "native";
|
|
81
125
|
});
|
|
126
|
+
// Getting all non-native (XLM) assets on the account
|
|
127
|
+
assets = account.balances?.filter((balance) => {
|
|
128
|
+
return balance.asset_type !== "native";
|
|
129
|
+
});
|
|
82
130
|
} catch (e) {
|
|
83
131
|
balance.balance = "0";
|
|
84
132
|
}
|
|
@@ -97,6 +145,7 @@ export const fetchAccount = async (
|
|
|
97
145
|
blockHeight: account.sequence ? Number(account.sequence) : undefined,
|
|
98
146
|
balance: formattedBalance,
|
|
99
147
|
spendableBalance,
|
|
148
|
+
assets,
|
|
100
149
|
};
|
|
101
150
|
};
|
|
102
151
|
|
|
@@ -105,16 +154,23 @@ export const fetchAccount = async (
|
|
|
105
154
|
*
|
|
106
155
|
* @param {string} accountId
|
|
107
156
|
* @param {string} addr
|
|
108
|
-
* @param {
|
|
157
|
+
* @param {string} order - "desc" or "asc" order of returned records
|
|
158
|
+
* @param {string} cursor - point to start fetching records
|
|
109
159
|
*
|
|
110
160
|
* @return {Operation[]}
|
|
111
161
|
*/
|
|
112
|
-
export const fetchOperations = async (
|
|
113
|
-
accountId
|
|
114
|
-
addr
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
162
|
+
export const fetchOperations = async ({
|
|
163
|
+
accountId,
|
|
164
|
+
addr,
|
|
165
|
+
order,
|
|
166
|
+
cursor,
|
|
167
|
+
}: {
|
|
168
|
+
accountId: string;
|
|
169
|
+
addr: string;
|
|
170
|
+
order: "asc" | "desc";
|
|
171
|
+
cursor: string;
|
|
172
|
+
}): Promise<Operation[]> => {
|
|
173
|
+
if (!addr) {
|
|
118
174
|
return [];
|
|
119
175
|
}
|
|
120
176
|
|
|
@@ -125,10 +181,11 @@ export const fetchOperations = async (
|
|
|
125
181
|
rawOperations = await server
|
|
126
182
|
.operations()
|
|
127
183
|
.forAccount(addr)
|
|
128
|
-
.join("transactions")
|
|
129
|
-
.includeFailed(true)
|
|
130
184
|
.limit(LIMIT)
|
|
131
|
-
.
|
|
185
|
+
.order(order)
|
|
186
|
+
.cursor(cursor)
|
|
187
|
+
.includeFailed(true)
|
|
188
|
+
.join("transactions")
|
|
132
189
|
.call();
|
|
133
190
|
} catch (e: any) {
|
|
134
191
|
// FIXME: terrible hacks, because Stellar SDK fails to cast network failures to typed errors in react-native...
|
|
@@ -175,6 +232,7 @@ export const fetchOperations = async (
|
|
|
175
232
|
|
|
176
233
|
return operations;
|
|
177
234
|
};
|
|
235
|
+
|
|
178
236
|
export const fetchAccountNetworkInfo = async (
|
|
179
237
|
account: Account
|
|
180
238
|
): Promise<NetworkInfo> => {
|
|
@@ -183,25 +241,24 @@ export const fetchAccountNetworkInfo = async (
|
|
|
183
241
|
.accounts()
|
|
184
242
|
.accountId(account.freshAddress)
|
|
185
243
|
.call();
|
|
186
|
-
const
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
.call();
|
|
191
|
-
const baseReserve = new BigNumber(
|
|
192
|
-
(ledger.base_reserve_in_stroops * (2 + numberOfEntries)).toString()
|
|
193
|
-
);
|
|
194
|
-
const fees = new BigNumber(ledger.base_fee_in_stroops.toString());
|
|
244
|
+
const baseReserve = getReservedBalance(extendedAccount);
|
|
245
|
+
const { recommendedFee, networkCongestionLevel, baseFee } =
|
|
246
|
+
await fetchBaseFee();
|
|
247
|
+
|
|
195
248
|
return {
|
|
196
249
|
family: "stellar",
|
|
197
|
-
fees,
|
|
250
|
+
fees: new BigNumber(recommendedFee.toString()),
|
|
251
|
+
baseFee: new BigNumber(baseFee.toString()),
|
|
198
252
|
baseReserve,
|
|
253
|
+
networkCongestionLevel,
|
|
199
254
|
};
|
|
200
255
|
} catch (error) {
|
|
201
256
|
return {
|
|
202
257
|
family: "stellar",
|
|
203
258
|
fees: new BigNumber(0),
|
|
259
|
+
baseFee: new BigNumber(0),
|
|
204
260
|
baseReserve: new BigNumber(0),
|
|
261
|
+
networkCongestionLevel: undefined,
|
|
205
262
|
};
|
|
206
263
|
}
|
|
207
264
|
};
|
|
@@ -213,7 +270,7 @@ export const fetchSequence = async (a: Account): Promise<BigNumber> => {
|
|
|
213
270
|
: new BigNumber(0);
|
|
214
271
|
};
|
|
215
272
|
|
|
216
|
-
export const fetchSigners = async (a: Account) => {
|
|
273
|
+
export const fetchSigners = async (a: Account): Promise<Signer[]> => {
|
|
217
274
|
try {
|
|
218
275
|
const extendedAccount = await server
|
|
219
276
|
.accounts()
|
|
@@ -238,15 +295,29 @@ export const broadcastTransaction = async (
|
|
|
238
295
|
return res.hash;
|
|
239
296
|
};
|
|
240
297
|
|
|
241
|
-
export const buildPaymentOperation = (
|
|
242
|
-
destination
|
|
243
|
-
amount
|
|
244
|
-
|
|
298
|
+
export const buildPaymentOperation = ({
|
|
299
|
+
destination,
|
|
300
|
+
amount,
|
|
301
|
+
assetCode,
|
|
302
|
+
assetIssuer,
|
|
303
|
+
}: {
|
|
304
|
+
destination: string;
|
|
305
|
+
amount: BigNumber;
|
|
306
|
+
assetCode: string | undefined;
|
|
307
|
+
assetIssuer: string | undefined;
|
|
308
|
+
}): any => {
|
|
245
309
|
const formattedAmount = getFormattedAmount(amount);
|
|
310
|
+
// Non-native assets should always have asset code and asset issuer. If an
|
|
311
|
+
// asset doesn't have both, we assume it is native asset.
|
|
312
|
+
const asset =
|
|
313
|
+
assetCode && assetIssuer
|
|
314
|
+
? new StellarSdk.Asset(assetCode, assetIssuer)
|
|
315
|
+
: StellarSdk.Asset.native();
|
|
246
316
|
return StellarSdk.Operation.payment({
|
|
247
317
|
destination: destination,
|
|
248
318
|
amount: formattedAmount,
|
|
249
|
-
asset
|
|
319
|
+
asset,
|
|
320
|
+
withMuxing: true,
|
|
250
321
|
});
|
|
251
322
|
};
|
|
252
323
|
|
|
@@ -261,6 +332,15 @@ export const buildCreateAccountOperation = (
|
|
|
261
332
|
});
|
|
262
333
|
};
|
|
263
334
|
|
|
335
|
+
export const buildChangeTrustOperation = (
|
|
336
|
+
assetCode: string,
|
|
337
|
+
assetIssuer: string
|
|
338
|
+
): any => {
|
|
339
|
+
return StellarSdk.Operation.changeTrust({
|
|
340
|
+
asset: new StellarSdk.Asset(assetCode, assetIssuer),
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
|
|
264
344
|
export const buildTransactionBuilder = (
|
|
265
345
|
source: typeof StellarSdk.Account,
|
|
266
346
|
fee: BigNumber
|
|
@@ -272,7 +352,9 @@ export const buildTransactionBuilder = (
|
|
|
272
352
|
});
|
|
273
353
|
};
|
|
274
354
|
|
|
275
|
-
export const loadAccount = async (
|
|
355
|
+
export const loadAccount = async (
|
|
356
|
+
addr: string
|
|
357
|
+
): Promise<AccountRecord | null> => {
|
|
276
358
|
if (!addr || !addr.length) {
|
|
277
359
|
return null;
|
|
278
360
|
}
|
|
@@ -111,11 +111,15 @@ const dataset: DatasetTest<Transaction> = {
|
|
|
111
111
|
networkInfo: {
|
|
112
112
|
family: "stellar",
|
|
113
113
|
fees: "100",
|
|
114
|
+
baseFee: "100",
|
|
114
115
|
baseReserve: "1500000",
|
|
115
116
|
},
|
|
116
117
|
fees: "100",
|
|
117
118
|
memoType: null,
|
|
118
119
|
memoValue: null,
|
|
120
|
+
mode: "send",
|
|
121
|
+
assetCode: "",
|
|
122
|
+
assetIssuer: "",
|
|
119
123
|
}),
|
|
120
124
|
expectedStatus: {
|
|
121
125
|
errors: {
|
|
@@ -166,18 +170,22 @@ const dataset: DatasetTest<Transaction> = {
|
|
|
166
170
|
networkInfo: {
|
|
167
171
|
family: "stellar",
|
|
168
172
|
fees: "100",
|
|
173
|
+
baseFee: "100",
|
|
169
174
|
baseReserve: "1500000",
|
|
170
175
|
},
|
|
171
176
|
fees: "100",
|
|
172
177
|
memoType: null,
|
|
173
178
|
memoValue: null,
|
|
179
|
+
mode: "send",
|
|
180
|
+
assetCode: "",
|
|
181
|
+
assetIssuer: "",
|
|
174
182
|
}),
|
|
175
183
|
expectedStatus: (account) => ({
|
|
176
184
|
errors: {},
|
|
177
185
|
warnings: {},
|
|
178
186
|
estimatedFees: new BigNumber("100"),
|
|
179
|
-
amount: account.
|
|
180
|
-
totalSpent: account.
|
|
187
|
+
amount: account.spendableBalance.minus("100"),
|
|
188
|
+
totalSpent: account.spendableBalance.minus("100"),
|
|
181
189
|
}),
|
|
182
190
|
},
|
|
183
191
|
{
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import invariant from "invariant";
|
|
2
|
-
import
|
|
2
|
+
import { getAccountCurrency } from "../../account";
|
|
3
|
+
import type {
|
|
4
|
+
Transaction,
|
|
5
|
+
AccountLike,
|
|
6
|
+
Account,
|
|
7
|
+
AccountLikeArray,
|
|
8
|
+
} from "../../types";
|
|
9
|
+
import { getAssetIdFromTokenId } from "./tokens";
|
|
10
|
+
|
|
3
11
|
const options = [
|
|
4
12
|
{
|
|
5
13
|
name: "fee",
|
|
@@ -16,6 +24,21 @@ const options = [
|
|
|
16
24
|
type: String,
|
|
17
25
|
desc: "stellar memo value",
|
|
18
26
|
},
|
|
27
|
+
{
|
|
28
|
+
name: "mode",
|
|
29
|
+
type: String,
|
|
30
|
+
desc: "change operation type",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "assetIssuer",
|
|
34
|
+
type: String,
|
|
35
|
+
desc: "Asset issuer",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "assetCode",
|
|
39
|
+
type: String,
|
|
40
|
+
desc: "Same as token",
|
|
41
|
+
},
|
|
19
42
|
];
|
|
20
43
|
|
|
21
44
|
function inferTransactions(
|
|
@@ -25,17 +48,67 @@ function inferTransactions(
|
|
|
25
48
|
}>,
|
|
26
49
|
opts: Record<string, any>
|
|
27
50
|
): Transaction[] {
|
|
28
|
-
return transactions.map(({ transaction }) => {
|
|
51
|
+
return transactions.map(({ transaction, account }) => {
|
|
29
52
|
invariant(transaction.family === "stellar", "stellar family");
|
|
53
|
+
|
|
30
54
|
return {
|
|
31
55
|
...transaction,
|
|
56
|
+
subAccountId: account.type === "TokenAccount" ? account.id : null,
|
|
32
57
|
memoType: opts.memoType,
|
|
33
58
|
memoValue: opts.memoValue,
|
|
59
|
+
mode: opts.mode ?? "send",
|
|
60
|
+
assetCode: opts.token,
|
|
61
|
+
assetIssuer: opts.assetIssuer,
|
|
34
62
|
};
|
|
35
63
|
});
|
|
36
64
|
}
|
|
37
65
|
|
|
66
|
+
function inferAccounts(
|
|
67
|
+
account: Account,
|
|
68
|
+
opts: Record<string, any>
|
|
69
|
+
): AccountLikeArray {
|
|
70
|
+
invariant(account.currency.family === "stellar", "stellar family");
|
|
71
|
+
|
|
72
|
+
if (opts.subAccountId) {
|
|
73
|
+
const assetSubAccount = account.subAccounts?.find(
|
|
74
|
+
(a) => a.id === opts.subAccountId
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
if (!assetSubAccount) {
|
|
78
|
+
throw new Error(`${opts.subAccountId} asset not found`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return [assetSubAccount];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (opts.assetCode) {
|
|
85
|
+
const subAccounts = account.subAccounts || [];
|
|
86
|
+
|
|
87
|
+
const subAccount = subAccounts.find((sa) => {
|
|
88
|
+
const currency = getAccountCurrency(sa);
|
|
89
|
+
return (
|
|
90
|
+
opts.assetCode.toLowerCase() === currency.ticker.toLowerCase() ||
|
|
91
|
+
opts.assetCode.toLowerCase() === getAssetIdFromTokenId(currency.id)
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (!subAccount) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
"token account '" +
|
|
98
|
+
opts.assetCode +
|
|
99
|
+
"' not found. Available: " +
|
|
100
|
+
subAccounts.map((t) => getAccountCurrency(t).ticker).join(", ")
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return [subAccount];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return [account];
|
|
108
|
+
}
|
|
109
|
+
|
|
38
110
|
export default {
|
|
39
111
|
options,
|
|
112
|
+
inferAccounts,
|
|
40
113
|
inferTransactions,
|
|
41
114
|
};
|
|
@@ -10,16 +10,27 @@ export type ExtraDeviceTransactionField =
|
|
|
10
10
|
| {
|
|
11
11
|
type: "stellar.network";
|
|
12
12
|
label: string;
|
|
13
|
+
}
|
|
14
|
+
| {
|
|
15
|
+
type: "stellar.assetCode";
|
|
16
|
+
label: string;
|
|
17
|
+
}
|
|
18
|
+
| {
|
|
19
|
+
type: "stellar.assetIssuer";
|
|
20
|
+
label: string;
|
|
13
21
|
};
|
|
14
22
|
|
|
15
23
|
function getDeviceTransactionConfig({
|
|
16
24
|
status: { amount, estimatedFees },
|
|
25
|
+
transaction,
|
|
17
26
|
}: {
|
|
18
27
|
account: AccountLike;
|
|
19
28
|
parentAccount: Account | null | undefined;
|
|
20
29
|
transaction: Transaction;
|
|
21
30
|
status: TransactionStatus;
|
|
22
31
|
}): Array<DeviceTransactionField | ExtraDeviceTransactionField> {
|
|
32
|
+
const { assetCode, assetIssuer } = transaction;
|
|
33
|
+
|
|
23
34
|
const fields: Array<DeviceTransactionField | ExtraDeviceTransactionField> = [
|
|
24
35
|
{
|
|
25
36
|
type: "stellar.network",
|
|
@@ -34,6 +45,17 @@ function getDeviceTransactionConfig({
|
|
|
34
45
|
});
|
|
35
46
|
}
|
|
36
47
|
|
|
48
|
+
if (assetCode && assetIssuer) {
|
|
49
|
+
fields.push({
|
|
50
|
+
type: "stellar.assetCode",
|
|
51
|
+
label: "Asset",
|
|
52
|
+
});
|
|
53
|
+
fields.push({
|
|
54
|
+
type: "stellar.assetIssuer",
|
|
55
|
+
label: "Asset issuer",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
37
59
|
fields.push({
|
|
38
60
|
type: "stellar.memo",
|
|
39
61
|
label: "Memo",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createCustomErrorClass } from "@ledgerhq/errors";
|
|
2
|
+
|
|
3
|
+
export const StellarMemoRecommended = createCustomErrorClass(
|
|
4
|
+
"StellarMemoRecommended"
|
|
5
|
+
);
|
|
6
|
+
export const StellarWrongMemoFormat = createCustomErrorClass(
|
|
7
|
+
"StellarWrongMemoFormat"
|
|
8
|
+
);
|
|
9
|
+
export const StellarAssetRequired = createCustomErrorClass(
|
|
10
|
+
"StellarAssetRequired"
|
|
11
|
+
);
|
|
12
|
+
export const StellarAssetNotAccepted = createCustomErrorClass(
|
|
13
|
+
"StellarAssetNotAccepted"
|
|
14
|
+
);
|
|
15
|
+
export const StellarAssetNotFound = createCustomErrorClass(
|
|
16
|
+
"StellarAssetNotFound"
|
|
17
|
+
);
|
|
18
|
+
export const StellarNotEnoughNativeBalance = createCustomErrorClass(
|
|
19
|
+
"StellarNotEnoughNativeBalance"
|
|
20
|
+
);
|
|
21
|
+
export const StellarFeeSmallerThanRecommended = createCustomErrorClass(
|
|
22
|
+
"StellarFeeSmallerThanRecommended"
|
|
23
|
+
);
|
|
24
|
+
export const StellarFeeSmallerThanBase = createCustomErrorClass(
|
|
25
|
+
"StellarFeeSmallerThanBase"
|
|
26
|
+
);
|
|
27
|
+
export const StellarNotEnoughNativeBalanceToAddTrustline =
|
|
28
|
+
createCustomErrorClass("StellarNotEnoughNativeBalanceToAddTrustline");
|
|
29
|
+
export const StellarMuxedAccountNotExist = createCustomErrorClass(
|
|
30
|
+
"StellarMuxedAccountNotExist"
|
|
31
|
+
);
|
|
32
|
+
export const StellarSourceHasMultiSign = createCustomErrorClass(
|
|
33
|
+
"StellarSourceHasMultiSign"
|
|
34
|
+
);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import invariant from "invariant";
|
|
2
|
-
import { BigNumber } from "bignumber.js";
|
|
3
2
|
import StellarSdk from "stellar-sdk";
|
|
4
3
|
import { AmountRequired, FeeNotLoaded, NetworkDown } from "@ledgerhq/errors";
|
|
5
4
|
import type { Account } from "../../types";
|
|
@@ -8,9 +7,14 @@ import {
|
|
|
8
7
|
buildPaymentOperation,
|
|
9
8
|
buildCreateAccountOperation,
|
|
10
9
|
buildTransactionBuilder,
|
|
10
|
+
buildChangeTrustOperation,
|
|
11
11
|
loadAccount,
|
|
12
12
|
} from "./api";
|
|
13
|
-
import {
|
|
13
|
+
import { getRecipientAccount, getAmountValue } from "./logic";
|
|
14
|
+
import {
|
|
15
|
+
StellarAssetRequired,
|
|
16
|
+
StellarMuxedAccountNotExist,
|
|
17
|
+
} from "../../errors";
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* @param {Account} a
|
|
@@ -20,33 +24,69 @@ export const buildTransaction = async (
|
|
|
20
24
|
account: Account,
|
|
21
25
|
transaction: Transaction
|
|
22
26
|
): Promise<any> => {
|
|
23
|
-
const {
|
|
24
|
-
|
|
27
|
+
const {
|
|
28
|
+
recipient,
|
|
29
|
+
networkInfo,
|
|
30
|
+
fees,
|
|
31
|
+
memoType,
|
|
32
|
+
memoValue,
|
|
33
|
+
mode,
|
|
34
|
+
assetCode,
|
|
35
|
+
assetIssuer,
|
|
36
|
+
} = transaction;
|
|
25
37
|
|
|
26
38
|
if (!fees) {
|
|
27
39
|
throw new FeeNotLoaded();
|
|
28
40
|
}
|
|
29
41
|
|
|
30
|
-
invariant(networkInfo && networkInfo.family === "stellar", "stellar family");
|
|
31
|
-
let amount = new BigNumber(0);
|
|
32
|
-
amount =
|
|
33
|
-
useAllAmount && networkInfo
|
|
34
|
-
? account.balance.minus(networkInfo.baseReserve).minus(fees)
|
|
35
|
-
: transaction.amount;
|
|
36
|
-
if (!amount) throw new AmountRequired();
|
|
37
42
|
const source = await loadAccount(account.freshAddress);
|
|
38
|
-
|
|
43
|
+
|
|
44
|
+
if (!source) {
|
|
45
|
+
throw new NetworkDown();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
invariant(networkInfo && networkInfo.family === "stellar", "stellar family");
|
|
49
|
+
|
|
39
50
|
const transactionBuilder = buildTransactionBuilder(source, fees);
|
|
40
51
|
let operation = null;
|
|
41
|
-
const recipientExists = await addressExists(transaction.recipient); // TODO: use cache with checkRecipientExist instead?
|
|
42
52
|
|
|
43
|
-
if (
|
|
44
|
-
|
|
53
|
+
if (mode === "changeTrust") {
|
|
54
|
+
if (!assetCode || !assetIssuer) {
|
|
55
|
+
throw new StellarAssetRequired("");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
operation = buildChangeTrustOperation(assetCode, assetIssuer);
|
|
45
59
|
} else {
|
|
46
|
-
|
|
60
|
+
// Payment
|
|
61
|
+
const amount = getAmountValue(account, transaction, fees);
|
|
62
|
+
|
|
63
|
+
if (!amount) {
|
|
64
|
+
throw new AmountRequired();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const recipientAccount = await getRecipientAccount({
|
|
68
|
+
account,
|
|
69
|
+
recipient: transaction.recipient,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (recipientAccount?.id) {
|
|
73
|
+
operation = buildPaymentOperation({
|
|
74
|
+
destination: recipient,
|
|
75
|
+
amount,
|
|
76
|
+
assetCode,
|
|
77
|
+
assetIssuer,
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
if (recipientAccount?.isMuxedAccount) {
|
|
81
|
+
throw new StellarMuxedAccountNotExist("");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
operation = buildCreateAccountOperation(recipient, amount);
|
|
85
|
+
}
|
|
47
86
|
}
|
|
48
87
|
|
|
49
88
|
transactionBuilder.addOperation(operation);
|
|
89
|
+
|
|
50
90
|
let memo = null;
|
|
51
91
|
|
|
52
92
|
if (memoType && memoValue) {
|