@ledgerhq/coin-stellar 6.26.0 → 6.26.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.
Files changed (271) hide show
  1. package/.oxlintrc.json +7 -0
  2. package/CHANGELOG.md +6 -0
  3. package/LICENSE +194 -0
  4. package/knip.json +12 -0
  5. package/lib/api/index.d.ts +5 -5
  6. package/lib/api/index.d.ts.map +1 -1
  7. package/lib/api/index.js +12 -10
  8. package/lib/api/index.js.map +1 -1
  9. package/lib/config.d.ts +1 -1
  10. package/lib/config.d.ts.map +1 -1
  11. package/lib/config.js +2 -0
  12. package/lib/config.js.map +1 -1
  13. package/lib/constants.d.ts.map +1 -1
  14. package/lib/constants.js +3 -1
  15. package/lib/constants.js.map +1 -1
  16. package/lib/logic/broadcast.d.ts.map +1 -1
  17. package/lib/logic/broadcast.js +2 -0
  18. package/lib/logic/broadcast.js.map +1 -1
  19. package/lib/logic/combine.d.ts +1 -1
  20. package/lib/logic/combine.d.ts.map +1 -1
  21. package/lib/logic/combine.js +2 -0
  22. package/lib/logic/combine.js.map +1 -1
  23. package/lib/logic/common.d.ts +1 -1
  24. package/lib/logic/common.d.ts.map +1 -1
  25. package/lib/logic/common.js +4 -2
  26. package/lib/logic/common.js.map +1 -1
  27. package/lib/logic/craftTransaction.d.ts +1 -1
  28. package/lib/logic/craftTransaction.d.ts.map +1 -1
  29. package/lib/logic/craftTransaction.js +10 -8
  30. package/lib/logic/craftTransaction.js.map +1 -1
  31. package/lib/logic/estimateFees.d.ts.map +1 -1
  32. package/lib/logic/estimateFees.js +2 -0
  33. package/lib/logic/estimateFees.js.map +1 -1
  34. package/lib/logic/getBalance.d.ts +1 -1
  35. package/lib/logic/getBalance.d.ts.map +1 -1
  36. package/lib/logic/getBalance.js +4 -2
  37. package/lib/logic/getBalance.js.map +1 -1
  38. package/lib/logic/getBlock.d.ts +1 -1
  39. package/lib/logic/getBlock.d.ts.map +1 -1
  40. package/lib/logic/getBlock.js +39 -34
  41. package/lib/logic/getBlock.js.map +1 -1
  42. package/lib/logic/getBlockInfo.d.ts +1 -1
  43. package/lib/logic/getBlockInfo.d.ts.map +1 -1
  44. package/lib/logic/getBlockInfo.js +2 -0
  45. package/lib/logic/getBlockInfo.js.map +1 -1
  46. package/lib/logic/index.d.ts +12 -12
  47. package/lib/logic/index.d.ts.map +1 -1
  48. package/lib/logic/index.js +2 -0
  49. package/lib/logic/index.js.map +1 -1
  50. package/lib/logic/lastBlock.d.ts +1 -1
  51. package/lib/logic/lastBlock.d.ts.map +1 -1
  52. package/lib/logic/lastBlock.js +2 -0
  53. package/lib/logic/lastBlock.js.map +1 -1
  54. package/lib/logic/listOperations.d.ts +1 -1
  55. package/lib/logic/listOperations.d.ts.map +1 -1
  56. package/lib/logic/listOperations.js +6 -4
  57. package/lib/logic/listOperations.js.map +1 -1
  58. package/lib/logic/sdkWrapper.d.ts +1 -1
  59. package/lib/logic/sdkWrapper.d.ts.map +1 -1
  60. package/lib/logic/sdkWrapper.js +2 -0
  61. package/lib/logic/sdkWrapper.js.map +1 -1
  62. package/lib/logic/utils.d.ts.map +1 -1
  63. package/lib/logic/utils.js +4 -2
  64. package/lib/logic/utils.js.map +1 -1
  65. package/lib/logic/validateAddress.d.ts +1 -1
  66. package/lib/logic/validateAddress.d.ts.map +1 -1
  67. package/lib/logic/validateAddress.js +2 -0
  68. package/lib/logic/validateAddress.js.map +1 -1
  69. package/lib/logic/validateIntent.d.ts +2 -2
  70. package/lib/logic/validateIntent.d.ts.map +1 -1
  71. package/lib/logic/validateIntent.js +21 -19
  72. package/lib/logic/validateIntent.js.map +1 -1
  73. package/lib/logic/validateMemo.d.ts +1 -1
  74. package/lib/logic/validateMemo.d.ts.map +1 -1
  75. package/lib/logic/validateMemo.js +7 -5
  76. package/lib/logic/validateMemo.js.map +1 -1
  77. package/lib/network/horizon.d.ts +6 -7
  78. package/lib/network/horizon.d.ts.map +1 -1
  79. package/lib/network/horizon.js +71 -68
  80. package/lib/network/horizon.js.map +1 -1
  81. package/lib/network/horizonLedgerErrors.d.ts.map +1 -1
  82. package/lib/network/horizonLedgerErrors.js +5 -3
  83. package/lib/network/horizonLedgerErrors.js.map +1 -1
  84. package/lib/network/index.d.ts +1 -1
  85. package/lib/network/index.d.ts.map +1 -1
  86. package/lib/network/index.js +2 -0
  87. package/lib/network/index.js.map +1 -1
  88. package/lib/network/serialization.d.ts +6 -4
  89. package/lib/network/serialization.d.ts.map +1 -1
  90. package/lib/network/serialization.js +95 -91
  91. package/lib/network/serialization.js.map +1 -1
  92. package/lib/polyfill.d.ts.map +1 -1
  93. package/lib/polyfill.js +6 -4
  94. package/lib/polyfill.js.map +1 -1
  95. package/lib/supportedFeatures.d.ts +1 -1
  96. package/lib/supportedFeatures.d.ts.map +1 -1
  97. package/lib/supportedFeatures.js +3 -1
  98. package/lib/supportedFeatures.js.map +1 -1
  99. package/lib/types/errors.d.ts.map +1 -1
  100. package/lib/types/errors.js +14 -12
  101. package/lib/types/errors.js.map +1 -1
  102. package/lib/types/index.d.ts +2 -2
  103. package/lib/types/index.d.ts.map +1 -1
  104. package/lib/types/index.js +2 -0
  105. package/lib/types/index.js.map +1 -1
  106. package/lib/types/model.d.ts +6 -6
  107. package/lib/types/model.d.ts.map +1 -1
  108. package/lib/types/model.js +7 -5
  109. package/lib/types/model.js.map +1 -1
  110. package/lib-es/api/index.d.ts +5 -5
  111. package/lib-es/api/index.d.ts.map +1 -1
  112. package/lib-es/api/index.js +20 -18
  113. package/lib-es/api/index.js.map +1 -1
  114. package/lib-es/config.d.ts +1 -1
  115. package/lib-es/config.d.ts.map +1 -1
  116. package/lib-es/config.js +3 -1
  117. package/lib-es/config.js.map +1 -1
  118. package/lib-es/constants.d.ts.map +1 -1
  119. package/lib-es/constants.js +3 -1
  120. package/lib-es/constants.js.map +1 -1
  121. package/lib-es/logic/broadcast.d.ts.map +1 -1
  122. package/lib-es/logic/broadcast.js +3 -1
  123. package/lib-es/logic/broadcast.js.map +1 -1
  124. package/lib-es/logic/combine.d.ts +1 -1
  125. package/lib-es/logic/combine.d.ts.map +1 -1
  126. package/lib-es/logic/combine.js +3 -1
  127. package/lib-es/logic/combine.js.map +1 -1
  128. package/lib-es/logic/common.d.ts +1 -1
  129. package/lib-es/logic/common.d.ts.map +1 -1
  130. package/lib-es/logic/common.js +5 -3
  131. package/lib-es/logic/common.js.map +1 -1
  132. package/lib-es/logic/craftTransaction.d.ts +1 -1
  133. package/lib-es/logic/craftTransaction.d.ts.map +1 -1
  134. package/lib-es/logic/craftTransaction.js +15 -13
  135. package/lib-es/logic/craftTransaction.js.map +1 -1
  136. package/lib-es/logic/estimateFees.d.ts.map +1 -1
  137. package/lib-es/logic/estimateFees.js +3 -1
  138. package/lib-es/logic/estimateFees.js.map +1 -1
  139. package/lib-es/logic/getBalance.d.ts +1 -1
  140. package/lib-es/logic/getBalance.d.ts.map +1 -1
  141. package/lib-es/logic/getBalance.js +5 -3
  142. package/lib-es/logic/getBalance.js.map +1 -1
  143. package/lib-es/logic/getBlock.d.ts +1 -1
  144. package/lib-es/logic/getBlock.d.ts.map +1 -1
  145. package/lib-es/logic/getBlock.js +42 -37
  146. package/lib-es/logic/getBlock.js.map +1 -1
  147. package/lib-es/logic/getBlockInfo.d.ts +1 -1
  148. package/lib-es/logic/getBlockInfo.d.ts.map +1 -1
  149. package/lib-es/logic/getBlockInfo.js +3 -1
  150. package/lib-es/logic/getBlockInfo.js.map +1 -1
  151. package/lib-es/logic/index.d.ts +12 -12
  152. package/lib-es/logic/index.d.ts.map +1 -1
  153. package/lib-es/logic/index.js +14 -12
  154. package/lib-es/logic/index.js.map +1 -1
  155. package/lib-es/logic/lastBlock.d.ts +1 -1
  156. package/lib-es/logic/lastBlock.d.ts.map +1 -1
  157. package/lib-es/logic/lastBlock.js +3 -1
  158. package/lib-es/logic/lastBlock.js.map +1 -1
  159. package/lib-es/logic/listOperations.d.ts +1 -1
  160. package/lib-es/logic/listOperations.d.ts.map +1 -1
  161. package/lib-es/logic/listOperations.js +7 -5
  162. package/lib-es/logic/listOperations.js.map +1 -1
  163. package/lib-es/logic/sdkWrapper.d.ts +1 -1
  164. package/lib-es/logic/sdkWrapper.d.ts.map +1 -1
  165. package/lib-es/logic/sdkWrapper.js +4 -2
  166. package/lib-es/logic/sdkWrapper.js.map +1 -1
  167. package/lib-es/logic/utils.d.ts.map +1 -1
  168. package/lib-es/logic/utils.js +6 -4
  169. package/lib-es/logic/utils.js.map +1 -1
  170. package/lib-es/logic/validateAddress.d.ts +1 -1
  171. package/lib-es/logic/validateAddress.d.ts.map +1 -1
  172. package/lib-es/logic/validateAddress.js +3 -1
  173. package/lib-es/logic/validateAddress.js.map +1 -1
  174. package/lib-es/logic/validateIntent.d.ts +2 -2
  175. package/lib-es/logic/validateIntent.d.ts.map +1 -1
  176. package/lib-es/logic/validateIntent.js +30 -28
  177. package/lib-es/logic/validateIntent.js.map +1 -1
  178. package/lib-es/logic/validateMemo.d.ts +1 -1
  179. package/lib-es/logic/validateMemo.d.ts.map +1 -1
  180. package/lib-es/logic/validateMemo.js +8 -6
  181. package/lib-es/logic/validateMemo.js.map +1 -1
  182. package/lib-es/network/horizon.d.ts +6 -7
  183. package/lib-es/network/horizon.d.ts.map +1 -1
  184. package/lib-es/network/horizon.js +80 -77
  185. package/lib-es/network/horizon.js.map +1 -1
  186. package/lib-es/network/horizonLedgerErrors.d.ts.map +1 -1
  187. package/lib-es/network/horizonLedgerErrors.js +7 -5
  188. package/lib-es/network/horizonLedgerErrors.js.map +1 -1
  189. package/lib-es/network/index.d.ts +1 -1
  190. package/lib-es/network/index.d.ts.map +1 -1
  191. package/lib-es/network/index.js +3 -1
  192. package/lib-es/network/index.js.map +1 -1
  193. package/lib-es/network/serialization.d.ts +6 -4
  194. package/lib-es/network/serialization.d.ts.map +1 -1
  195. package/lib-es/network/serialization.js +97 -95
  196. package/lib-es/network/serialization.js.map +1 -1
  197. package/lib-es/polyfill.d.ts.map +1 -1
  198. package/lib-es/polyfill.js +7 -5
  199. package/lib-es/polyfill.js.map +1 -1
  200. package/lib-es/supportedFeatures.d.ts +1 -1
  201. package/lib-es/supportedFeatures.d.ts.map +1 -1
  202. package/lib-es/supportedFeatures.js +3 -1
  203. package/lib-es/supportedFeatures.js.map +1 -1
  204. package/lib-es/types/errors.d.ts.map +1 -1
  205. package/lib-es/types/errors.js +15 -13
  206. package/lib-es/types/errors.js.map +1 -1
  207. package/lib-es/types/index.d.ts +2 -2
  208. package/lib-es/types/index.d.ts.map +1 -1
  209. package/lib-es/types/index.js +4 -2
  210. package/lib-es/types/index.js.map +1 -1
  211. package/lib-es/types/model.d.ts +6 -6
  212. package/lib-es/types/model.d.ts.map +1 -1
  213. package/lib-es/types/model.js +7 -5
  214. package/lib-es/types/model.js.map +1 -1
  215. package/package.json +13 -16
  216. package/src/api/index.integ.test.ts +165 -162
  217. package/src/api/index.test.ts +106 -103
  218. package/src/api/index.ts +49 -46
  219. package/src/api/index_error.test.ts +48 -25
  220. package/src/config.ts +15 -12
  221. package/src/constants.ts +4 -1
  222. package/src/globals.d.ts +7 -5
  223. package/src/logic/broadcast.integ.test.ts +22 -19
  224. package/src/logic/broadcast.ts +5 -2
  225. package/src/logic/combine.test.ts +18 -15
  226. package/src/logic/combine.ts +8 -5
  227. package/src/logic/common.ts +9 -6
  228. package/src/logic/craftTransaction.test.ts +76 -75
  229. package/src/logic/craftTransaction.ts +46 -43
  230. package/src/logic/estimateFees.ts +6 -3
  231. package/src/logic/getBalance.test.ts +31 -28
  232. package/src/logic/getBalance.ts +13 -10
  233. package/src/logic/getBlock.integ.test.ts +40 -39
  234. package/src/logic/getBlock.test.ts +462 -415
  235. package/src/logic/getBlock.ts +142 -127
  236. package/src/logic/getBlockInfo.test.ts +72 -69
  237. package/src/logic/getBlockInfo.ts +15 -12
  238. package/src/logic/index.ts +15 -12
  239. package/src/logic/lastBlock.ts +6 -3
  240. package/src/logic/listOperations.ts +14 -11
  241. package/src/logic/listOperations.unit.test.ts +212 -209
  242. package/src/logic/networkWrappers.test.ts +32 -29
  243. package/src/logic/sdkWrapper.ts +19 -16
  244. package/src/logic/utils.ts +13 -10
  245. package/src/logic/validateAddress.test.ts +21 -18
  246. package/src/logic/validateAddress.ts +7 -4
  247. package/src/logic/validateIntent.test.ts +62 -59
  248. package/src/logic/validateIntent.ts +87 -84
  249. package/src/logic/validateMemo.test.ts +50 -47
  250. package/src/logic/validateMemo.ts +16 -13
  251. package/src/network/broadcastTransaction.test.ts +60 -60
  252. package/src/network/fetchLedgerOperations.unit.test.ts +155 -0
  253. package/src/network/horizon.integ.test.ts +45 -42
  254. package/src/network/horizon.test.ts +17 -14
  255. package/src/network/horizon.ts +279 -281
  256. package/src/network/horizon.unit.test.ts +238 -237
  257. package/src/network/horizonLedgerErrors.test.ts +81 -78
  258. package/src/network/horizonLedgerErrors.ts +22 -19
  259. package/src/network/index.ts +4 -1
  260. package/src/network/registerHorizonInterceptors.test.ts +163 -160
  261. package/src/network/serialization.ts +232 -227
  262. package/src/network/serialization.unit.test.ts +801 -798
  263. package/src/polyfill.ts +18 -15
  264. package/src/supportedFeatures.ts +6 -3
  265. package/src/types/errors.ts +33 -32
  266. package/src/types/index.ts +5 -2
  267. package/src/types/model.ts +55 -52
  268. package/tsconfig.json +1 -1
  269. package/.unimportedrc.json +0 -17
  270. package/LICENSE.txt +0 -21
  271. package/src/network/fetchLedgerOperations.nock.unit.test.ts +0 -156
@@ -1,8 +1,11 @@
1
- import type { Operation, Page } from "@ledgerhq/coin-module-framework/api/types";
2
- import { LedgerAPI4xx, LedgerAPI5xx, NetworkDown } from "@ledgerhq/errors";
3
- import type { CacheRes } from "@ledgerhq/live-network/cache";
4
- import { makeLRUCache } from "@ledgerhq/live-network/cache";
5
- import { log } from "@ledgerhq/logs";
1
+ // SPDX-FileCopyrightText: © 2026 LEDGER SAS
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { Operation, Page } from '@ledgerhq/coin-module-framework/api/types'
5
+ import type { CacheRes } from '@ledgerhq/live-network/cache'
6
+ import { LedgerAPI4xx, LedgerAPI5xx, NetworkDown } from '@ledgerhq/errors'
7
+ import { makeLRUCache } from '@ledgerhq/live-network/cache'
8
+ import { log } from '@ledgerhq/logs'
6
9
  import {
7
10
  BadResponseError,
8
11
  BASE_FEE,
@@ -14,79 +17,79 @@ import {
14
17
  Transaction as StellarSdkTransaction,
15
18
  StrKey,
16
19
  xdr,
17
- } from "@stellar/stellar-sdk";
18
- import { BigNumber } from "bignumber.js";
19
- import coinConfig from "../config";
20
- import { patchHermesTypedArraysIfNeeded, unpatchHermesTypedArrays } from "../polyfill";
21
- import { StellarBroadcastFailedError, type StellarDecodedResultXdr } from "../types/errors";
20
+ } from '@stellar/stellar-sdk'
21
+ import { BigNumber } from 'bignumber.js'
22
+ import coinConfig from '../config'
23
+ import { parseAPIValue } from '../logic/common'
24
+ import { patchHermesTypedArraysIfNeeded, unpatchHermesTypedArrays } from '../polyfill'
22
25
  import {
23
26
  type BalanceAsset,
24
27
  type NetworkInfo,
25
28
  type RawOperation,
26
29
  type Signer,
27
30
  NetworkCongestionLevel,
28
- } from "../types";
29
- import { getReservedBalance, rawOperationsToOperations } from "./serialization";
30
- import { throwHorizonLedgerOrOperationsError } from "./horizonLedgerErrors";
31
- import { parseAPIValue } from "../logic/common";
31
+ } from '../types'
32
+ import { StellarBroadcastFailedError, type StellarDecodedResultXdr } from '../types/errors'
33
+ import { throwHorizonLedgerOrOperationsError } from './horizonLedgerErrors'
34
+ import { getReservedBalance, rawOperationsToOperations } from './serialization'
32
35
 
33
- const FALLBACK_BASE_FEE = 100;
34
- const TRESHOLD_LOW = 0.5;
35
- const TRESHOLD_MEDIUM = 0.75;
36
- const FETCH_LIMIT = 100;
36
+ const FALLBACK_BASE_FEE = 100
37
+ const TRESHOLD_LOW = 0.5
38
+ const TRESHOLD_MEDIUM = 0.75
39
+ const FETCH_LIMIT = 100
37
40
 
38
41
  const STELLAR_TX_RESULT_CODES_DOC_URL =
39
- "https://developers.stellar.org/docs/data/apis/horizon/api-reference/errors/result-codes/transactions";
42
+ 'https://developers.stellar.org/docs/data/apis/horizon/api-reference/errors/result-codes/transactions'
40
43
 
41
44
  /** Horizon `extras.result_codes.transaction` → one-line description (Stellar docs). */
42
45
  const HORIZON_TRANSACTION_RESULT_CODE_DOCUMENTATION: Record<string, string> = {
43
- tx_success: "The transaction succeeded.",
44
- tx_failed: "One of the operations failed (none were applied).",
45
- tx_too_early: "The ledger closeTime was before the minTime.",
46
- tx_too_late: "The ledger closeTime was after the maxTime.",
47
- tx_missing_operation: "No operation was specified.",
48
- tx_bad_seq: "Sequence number does not match source account.",
49
- tx_bad_auth: "Too few valid signatures / wrong network.",
50
- tx_insufficient_balance: "Fee would bring account below reserve.",
51
- tx_no_source_account: "Source account not found.",
52
- tx_insufficient_fee: "Fee is too small.",
53
- tx_bad_auth_extra: "Unused signatures attached to transaction.",
54
- tx_internal_error: "An unknown error occurred.",
55
- tx_fee_bump_inner_success: "Fee bump inner transaction succeeded.",
56
- tx_fee_bump_inner_failed: "Fee bump inner transaction failed.",
57
- tx_not_supported: "Transaction type not supported.",
58
- tx_bad_sponsorship: "Sponsorship is invalid.",
59
- tx_bad_min_seq_age_or_gap: "Minimum sequence age or gap precondition failed.",
60
- tx_malformed: "Transaction is malformed.",
61
- tx_soroban_invalid: "Soroban transaction is invalid.",
62
- };
46
+ tx_success: 'The transaction succeeded.',
47
+ tx_failed: 'One of the operations failed (none were applied).',
48
+ tx_too_early: 'The ledger closeTime was before the minTime.',
49
+ tx_too_late: 'The ledger closeTime was after the maxTime.',
50
+ tx_missing_operation: 'No operation was specified.',
51
+ tx_bad_seq: 'Sequence number does not match source account.',
52
+ tx_bad_auth: 'Too few valid signatures / wrong network.',
53
+ tx_insufficient_balance: 'Fee would bring account below reserve.',
54
+ tx_no_source_account: 'Source account not found.',
55
+ tx_insufficient_fee: 'Fee is too small.',
56
+ tx_bad_auth_extra: 'Unused signatures attached to transaction.',
57
+ tx_internal_error: 'An unknown error occurred.',
58
+ tx_fee_bump_inner_success: 'Fee bump inner transaction succeeded.',
59
+ tx_fee_bump_inner_failed: 'Fee bump inner transaction failed.',
60
+ tx_not_supported: 'Transaction type not supported.',
61
+ tx_bad_sponsorship: 'Sponsorship is invalid.',
62
+ tx_bad_min_seq_age_or_gap: 'Minimum sequence age or gap precondition failed.',
63
+ tx_malformed: 'Transaction is malformed.',
64
+ tx_soroban_invalid: 'Soroban transaction is invalid.',
65
+ }
63
66
 
64
67
  type HorizonSubmitErrorBody = {
65
- type?: string;
66
- title?: string;
67
- status?: number;
68
- detail?: string;
68
+ type?: string
69
+ title?: string
70
+ status?: number
71
+ detail?: string
69
72
  extras?: {
70
- envelope_xdr?: string;
71
- result_xdr?: string;
73
+ envelope_xdr?: string
74
+ result_xdr?: string
72
75
  result_codes?: {
73
- transaction?: string;
74
- operations?: string[];
75
- };
76
- };
77
- };
76
+ transaction?: string
77
+ operations?: string[]
78
+ }
79
+ }
80
+ }
78
81
 
79
82
  function isHorizonSubmitErrorBody(data: unknown): data is HorizonSubmitErrorBody {
80
83
  return !!(
81
84
  data &&
82
- typeof data === "object" &&
83
- "extras" in data &&
84
- typeof data.extras === "object" &&
85
+ typeof data === 'object' &&
86
+ 'extras' in data &&
87
+ typeof data.extras === 'object' &&
85
88
  data.extras !== null &&
86
- "result_codes" in data.extras &&
89
+ 'result_codes' in data.extras &&
87
90
  data.extras.result_codes !== undefined &&
88
- typeof data.extras.result_codes === "object"
89
- );
91
+ typeof data.extras.result_codes === 'object'
92
+ )
90
93
  }
91
94
 
92
95
  /**
@@ -96,58 +99,58 @@ function isHorizonSubmitErrorBody(data: unknown): data is HorizonSubmitErrorBody
96
99
  */
97
100
  function getHorizonBodyFromSubmitFailure(error: unknown): HorizonSubmitErrorBody | null {
98
101
  if (error instanceof BadResponseError && isHorizonSubmitErrorBody(error.response)) {
99
- return error.response;
102
+ return error.response
100
103
  }
101
- if (error && typeof error === "object" && "response" in error) {
102
- const data = (error as { response?: { data?: unknown } }).response?.data;
104
+ if (error && typeof error === 'object' && 'response' in error) {
105
+ const data = (error as { response?: { data?: unknown } }).response?.data
103
106
  if (isHorizonSubmitErrorBody(data)) {
104
- return data;
107
+ return data
105
108
  }
106
109
  }
107
- return null;
110
+ return null
108
111
  }
109
112
 
110
113
  function decodeTransactionResultFields(resultXdrBase64: string | undefined):
111
114
  | {
112
- feeChargedStroops?: string;
113
- resultXdrSwitchName?: string;
114
- decodedResultXdr: StellarDecodedResultXdr;
115
+ feeChargedStroops?: string
116
+ resultXdrSwitchName?: string
117
+ decodedResultXdr: StellarDecodedResultXdr
115
118
  }
116
119
  | undefined {
117
120
  if (!resultXdrBase64) {
118
- return undefined;
121
+ return undefined
119
122
  }
120
123
  try {
121
- const tr = xdr.TransactionResult.fromXDR(resultXdrBase64, "base64");
122
- const feeChargedStroops = tr.feeCharged().toString();
123
- const resultXdrSwitchName = tr.result().switch().name;
124
+ const tr = xdr.TransactionResult.fromXDR(resultXdrBase64, 'base64')
125
+ const feeChargedStroops = tr.feeCharged().toString()
126
+ const resultXdrSwitchName = tr.result().switch().name
124
127
  const decodedResultXdr: StellarDecodedResultXdr = {
125
128
  feeChargedStroops,
126
129
  resultSwitch: resultXdrSwitchName,
127
- };
128
- return { feeChargedStroops, resultXdrSwitchName, decodedResultXdr };
130
+ }
131
+ return { feeChargedStroops, resultXdrSwitchName, decodedResultXdr }
129
132
  } catch {
130
133
  return {
131
134
  decodedResultXdr: { decodeFailed: true, rawResultXdrBase64: resultXdrBase64 },
132
- };
135
+ }
133
136
  }
134
137
  }
135
138
 
136
139
  function makeBroadcastFailedError(body: HorizonSubmitErrorBody, cause: Error): Error {
137
- const extras = body.extras;
138
- const horizonTransactionCode = extras?.result_codes?.transaction ?? "";
139
- const horizonOperationCodes = extras?.result_codes?.operations;
140
+ const extras = body.extras
141
+ const horizonTransactionCode = extras?.result_codes?.transaction ?? ''
142
+ const horizonOperationCodes = extras?.result_codes?.operations
140
143
  const documentationSummary =
141
144
  (horizonTransactionCode &&
142
145
  HORIZON_TRANSACTION_RESULT_CODE_DOCUMENTATION[horizonTransactionCode]) ||
143
- "Unknown transaction result code.";
144
- const decodedResult = decodeTransactionResultFields(extras?.result_xdr);
145
- const feeChargedStroops = decodedResult?.feeChargedStroops;
146
- const resultXdrSwitchName = decodedResult?.resultXdrSwitchName;
147
- const decodedResultXdr = decodedResult?.decodedResultXdr;
148
- const envelopeXdr = extras?.envelope_xdr ?? "";
146
+ 'Unknown transaction result code.'
147
+ const decodedResult = decodeTransactionResultFields(extras?.result_xdr)
148
+ const feeChargedStroops = decodedResult?.feeChargedStroops
149
+ const resultXdrSwitchName = decodedResult?.resultXdrSwitchName
150
+ const decodedResultXdr = decodedResult?.decodedResultXdr
151
+ const envelopeXdr = extras?.envelope_xdr ?? ''
149
152
  const message =
150
- body.detail || body.title || `Transaction submission failed (${body.status ?? "unknown"}).`;
153
+ body.detail || body.title || `Transaction submission failed (${body.status ?? 'unknown'}).`
151
154
 
152
155
  return new StellarBroadcastFailedError(
153
156
  message,
@@ -161,28 +164,28 @@ function makeBroadcastFailedError(body: HorizonSubmitErrorBody, cause: Error): E
161
164
  decodedResultXdr,
162
165
  envelopeXdr,
163
166
  },
164
- { cause },
165
- );
167
+ { cause }
168
+ )
166
169
  }
167
170
 
168
171
  // Horizon client instance is cached to avoid costly rebuild at every request
169
172
  // Watch out: cache key is the URL, coin module can be instantiated several times with different URLs
170
- const servers = new Map<string, Horizon.Server>();
173
+ const servers = new Map<string, Horizon.Server>()
171
174
  function getServer(): Horizon.Server {
172
- const url = coinConfig.getCoinConfig().explorer.url;
173
- let server = servers.get(url);
175
+ const url = coinConfig.getCoinConfig().explorer.url
176
+ let server = servers.get(url)
174
177
  if (server === undefined) {
175
- server = new Horizon.Server(url);
176
- servers.set(url, server);
178
+ server = new Horizon.Server(url)
179
+ servers.set(url, server)
177
180
  }
178
- return server;
181
+ return server
179
182
  }
180
183
 
181
184
  // Tracks request start times for response-duration logging.
182
185
  // WeakMap avoids mutating the feaxios request config (whose type doesn't include `metadata`).
183
- const requestStartTimes = new WeakMap<object, number>();
186
+ const requestStartTimes = new WeakMap<object, number>()
184
187
 
185
- let interceptorsRegistered = false;
188
+ let interceptorsRegistered = false
186
189
 
187
190
  /**
188
191
  * Register logging and URL-fix interceptors on Horizon.AxiosClient.
@@ -193,83 +196,83 @@ let interceptorsRegistered = false;
193
196
  * InterceptorManager types rather than importing live-network's axios-typed interceptors.
194
197
  */
195
198
  export function registerHorizonInterceptors(): void {
196
- if (interceptorsRegistered) return;
197
- interceptorsRegistered = true;
199
+ if (interceptorsRegistered) return
200
+ interceptorsRegistered = true
198
201
 
199
- Horizon.AxiosClient.interceptors.request.use(config => {
200
- let enableNetworkLogs = false;
202
+ Horizon.AxiosClient.interceptors.request.use((config) => {
203
+ let enableNetworkLogs = false
201
204
  try {
202
- enableNetworkLogs = !!coinConfig.getCoinConfig().enableNetworkLogs;
205
+ enableNetworkLogs = !!coinConfig.getCoinConfig().enableNetworkLogs
203
206
  } catch {
204
- return config;
207
+ return config
205
208
  }
206
209
  if (enableNetworkLogs) {
207
- const { baseURL, url, method = "", data } = config;
208
- log("network", `${method} ${baseURL ?? ""}${url}`, { data });
209
- requestStartTimes.set(config, Date.now());
210
+ const { baseURL, url, method = '', data } = config
211
+ log('network', `${method} ${baseURL ?? ''}${url}`, { data })
212
+ requestStartTimes.set(config, Date.now())
210
213
  }
211
- return config;
212
- });
214
+ return config
215
+ })
213
216
 
214
- Horizon.AxiosClient.interceptors.response.use(response => {
215
- let enableNetworkLogs = false;
217
+ Horizon.AxiosClient.interceptors.response.use((response) => {
218
+ let enableNetworkLogs = false
216
219
  try {
217
- enableNetworkLogs = !!coinConfig.getCoinConfig().enableNetworkLogs;
220
+ enableNetworkLogs = !!coinConfig.getCoinConfig().enableNetworkLogs
218
221
  } catch {
219
222
  // coinConfig not initialised on this instance; skip logging and leave URLs untouched
220
223
  }
221
224
  if (enableNetworkLogs) {
222
225
  // response.config is typed as `any` in stellar-sdk's HttpClientResponse
223
- const startTime = requestStartTimes.get(response.config) ?? 0;
224
- requestStartTimes.delete(response.config);
226
+ const startTime = requestStartTimes.get(response.config) ?? 0
227
+ requestStartTimes.delete(response.config)
225
228
  log(
226
- "network-success",
227
- `${response.status} ${response.config?.method ?? ""} ${response.config?.baseURL ?? ""}${response.config?.url ?? ""} (${(Date.now() - startTime).toFixed(0)}ms)`,
228
- { data: response.data },
229
- );
229
+ 'network-success',
230
+ `${response.status} ${response.config?.method ?? ''} ${response.config?.baseURL ?? ''}${response.config?.url ?? ''} (${(Date.now() - startTime).toFixed(0)}ms)`,
231
+ { data: response.data }
232
+ )
230
233
  }
231
234
 
232
235
  // FIXME: workaround for the Stellar SDK not using the correct URL: the "next" URL
233
236
  // included in server responses points to the node itself instead of our reverse proxy...
234
237
  // (https://github.com/stellar/js-stellar-sdk/issues/637)
235
- const next_href = response?.data?._links?.next?.href;
238
+ const next_href = response?.data?._links?.next?.href
236
239
  if (next_href) {
237
- response.data._links.next.href = useConfigHostAndProtocol(next_href);
240
+ response.data._links.next.href = useConfigHostAndProtocol(next_href)
238
241
  }
239
242
  response?.data?._embedded?.records?.forEach((r: any) => {
240
- const href = r.transaction?._links?.ledger?.href;
241
- if (href) r.transaction._links.ledger.href = useConfigHostAndProtocol(href);
242
- });
243
+ const href = r.transaction?._links?.ledger?.href
244
+ if (href) r.transaction._links.ledger.href = useConfigHostAndProtocol(href)
245
+ })
243
246
 
244
- return response;
245
- });
247
+ return response
248
+ })
246
249
  }
247
250
 
248
251
  // It replaces the host and the protocol of the URL returned with the original ones.
249
252
  export function useConfigHostAndProtocol(url: string): string {
250
- const originalUrl = new URL(coinConfig.getCoinConfig().explorer.url);
253
+ const originalUrl = new URL(coinConfig.getCoinConfig().explorer.url)
251
254
  // URL.protocol setter silently fails when changing between special (https://) and
252
255
  // non-special (injected://) schemes, so reconstruct via string replacement instead.
253
- return url.replace(/^[^:]+:\/\/[^/]+/, `${originalUrl.protocol}//${originalUrl.host}`);
256
+ return url.replace(/^[^:]+:\/\/[^/]+/, `${originalUrl.protocol}//${originalUrl.host}`)
254
257
  }
255
258
 
256
259
  const getMinimumBalance = (account: Horizon.ServerApi.AccountRecord): BigNumber => {
257
- return parseAPIValue(getReservedBalance(account).toString());
258
- };
260
+ return parseAPIValue(getReservedBalance(account).toString())
261
+ }
259
262
 
260
263
  export async function getAccountSpendableBalance(
261
264
  balance: BigNumber,
262
- account: Horizon.ServerApi.AccountRecord,
265
+ account: Horizon.ServerApi.AccountRecord
263
266
  ): Promise<BigNumber> {
264
- const minimumBalance = getMinimumBalance(account);
265
- const { recommendedFee } = await fetchBaseFee();
266
- return BigNumber.max(balance.minus(minimumBalance).minus(recommendedFee), 0);
267
+ const minimumBalance = getMinimumBalance(account)
268
+ const { recommendedFee } = await fetchBaseFee()
269
+ return BigNumber.max(balance.minus(minimumBalance).minus(recommendedFee), 0)
267
270
  }
268
271
 
269
272
  export async function fetchBaseFee(): Promise<{
270
- baseFee: number;
271
- recommendedFee: number;
272
- networkCongestionLevel: NetworkCongestionLevel;
273
+ baseFee: number
274
+ recommendedFee: number
275
+ networkCongestionLevel: NetworkCongestionLevel
273
276
  }> {
274
277
  // For tests
275
278
  if (coinConfig.getCoinConfig().useStaticFees) {
@@ -277,27 +280,27 @@ export async function fetchBaseFee(): Promise<{
277
280
  baseFee: 100,
278
281
  recommendedFee: 100,
279
282
  networkCongestionLevel: NetworkCongestionLevel.LOW,
280
- };
283
+ }
281
284
  }
282
285
 
283
- const baseFee = new BigNumber(BASE_FEE).toNumber() || FALLBACK_BASE_FEE;
284
- let recommendedFee = baseFee;
285
- let networkCongestionLevel = NetworkCongestionLevel.MEDIUM;
286
+ const baseFee = new BigNumber(BASE_FEE).toNumber() || FALLBACK_BASE_FEE
287
+ let recommendedFee = baseFee
288
+ let networkCongestionLevel = NetworkCongestionLevel.MEDIUM
286
289
 
287
290
  try {
288
- const feeStats = await getServer().feeStats();
289
- const ledgerCapacityUsage = feeStats.ledger_capacity_usage;
290
- recommendedFee = new BigNumber(feeStats.fee_charged.mode).toNumber();
291
+ const feeStats = await getServer().feeStats()
292
+ const ledgerCapacityUsage = feeStats.ledger_capacity_usage
293
+ recommendedFee = new BigNumber(feeStats.fee_charged.mode).toNumber()
291
294
 
292
295
  if (
293
296
  new BigNumber(ledgerCapacityUsage).toNumber() > TRESHOLD_LOW &&
294
297
  new BigNumber(ledgerCapacityUsage).toNumber() <= TRESHOLD_MEDIUM
295
298
  ) {
296
- networkCongestionLevel = NetworkCongestionLevel.MEDIUM;
299
+ networkCongestionLevel = NetworkCongestionLevel.MEDIUM
297
300
  } else if (new BigNumber(ledgerCapacityUsage).toNumber() > TRESHOLD_MEDIUM) {
298
- networkCongestionLevel = NetworkCongestionLevel.HIGH;
301
+ networkCongestionLevel = NetworkCongestionLevel.HIGH
299
302
  } else {
300
- networkCongestionLevel = NetworkCongestionLevel.LOW;
303
+ networkCongestionLevel = NetworkCongestionLevel.LOW
301
304
  }
302
305
  } catch {
303
306
  // do nothing, will use defaults
@@ -307,7 +310,7 @@ export async function fetchBaseFee(): Promise<{
307
310
  baseFee,
308
311
  recommendedFee,
309
312
  networkCongestionLevel,
310
- };
313
+ }
311
314
  }
312
315
 
313
316
  /**
@@ -317,39 +320,39 @@ export async function fetchBaseFee(): Promise<{
317
320
  * @param {string} addr
318
321
  */
319
322
  export async function fetchAccount(addr: string): Promise<{
320
- blockHeight: number;
321
- balance: BigNumber;
322
- spendableBalance: BigNumber;
323
- assets: BalanceAsset[];
323
+ blockHeight: number
324
+ balance: BigNumber
325
+ spendableBalance: BigNumber
326
+ assets: BalanceAsset[]
324
327
  }> {
325
- let account: Horizon.ServerApi.AccountRecord = {} as Horizon.ServerApi.AccountRecord;
326
- let assets: BalanceAsset[] = [];
327
- let balance = "0";
328
+ let account: Horizon.ServerApi.AccountRecord = {} as Horizon.ServerApi.AccountRecord
329
+ let assets: BalanceAsset[] = []
330
+ let balance = '0'
328
331
 
329
332
  try {
330
- account = await getServer().accounts().accountId(addr).call();
333
+ account = await getServer().accounts().accountId(addr).call()
331
334
  balance =
332
- account.balances?.find(balance => {
333
- return balance.asset_type === "native";
334
- })?.balance || "0";
335
+ account.balances?.find((balance) => {
336
+ return balance.asset_type === 'native'
337
+ })?.balance || '0'
335
338
  // Getting all non-native (XLM) assets on the account
336
- assets = account.balances?.filter(balance => {
337
- return balance.asset_type !== "native";
338
- }) as BalanceAsset[];
339
+ assets = account.balances?.filter((balance) => {
340
+ return balance.asset_type !== 'native'
341
+ }) as BalanceAsset[]
339
342
  } catch {
340
- balance = "0";
343
+ balance = '0'
341
344
  }
342
345
 
343
- const formattedBalance = parseAPIValue(balance);
346
+ const formattedBalance = parseAPIValue(balance)
344
347
 
345
- const spendableBalance = await getAccountSpendableBalance(formattedBalance, account);
348
+ const spendableBalance = await getAccountSpendableBalance(formattedBalance, account)
346
349
 
347
350
  return {
348
351
  blockHeight: account.sequence ? new BigNumber(account.sequence).toNumber() : 0,
349
352
  balance: formattedBalance,
350
353
  spendableBalance,
351
354
  assets,
352
- };
355
+ }
353
356
  }
354
357
 
355
358
  /**
@@ -366,17 +369,17 @@ export async function fetchAccount(addr: string): Promise<{
366
369
  export async function fetchAllOperations(
367
370
  accountId: string,
368
371
  addr: string,
369
- order: "asc" | "desc",
370
- cursor: string = "",
371
- maxOperations?: number,
372
+ order: 'asc' | 'desc',
373
+ cursor: string = '',
374
+ maxOperations?: number
372
375
  ): Promise<Operation[]> {
373
376
  if (!addr) {
374
- return [];
377
+ return []
375
378
  }
376
379
 
377
- const limit = coinConfig.getCoinConfig().explorer.fetchLimit ?? FETCH_LIMIT;
378
- let operations: Operation[] = [];
379
- let fetchedOpsCount = limit;
380
+ const limit = coinConfig.getCoinConfig().explorer.fetchLimit ?? FETCH_LIMIT
381
+ let operations: Operation[] = []
382
+ let fetchedOpsCount = limit
380
383
 
381
384
  try {
382
385
  let rawOperations = await getServer()
@@ -386,50 +389,45 @@ export async function fetchAllOperations(
386
389
  .order(order)
387
390
  .cursor(cursor)
388
391
  .includeFailed(true)
389
- .join("transactions")
390
- .call();
392
+ .join('transactions')
393
+ .call()
391
394
 
392
395
  if (!rawOperations || !rawOperations.records.length) {
393
- return [];
396
+ return []
394
397
  }
395
398
 
396
399
  operations = operations.concat(
397
- await rawOperationsToOperations(rawOperations.records as RawOperation[], addr, accountId, 0),
398
- );
400
+ await rawOperationsToOperations(rawOperations.records as RawOperation[], addr, accountId, 0)
401
+ )
399
402
 
400
403
  while (rawOperations.records.length > 0) {
401
404
  if (maxOperations && fetchedOpsCount >= maxOperations) {
402
- break;
405
+ break
403
406
  }
404
- fetchedOpsCount += limit;
407
+ fetchedOpsCount += limit
405
408
 
406
- rawOperations = await rawOperations.next();
409
+ rawOperations = await rawOperations.next()
407
410
  operations = operations.concat(
408
- await rawOperationsToOperations(
409
- rawOperations.records as RawOperation[],
410
- addr,
411
- accountId,
412
- 0,
413
- ),
414
- );
411
+ await rawOperationsToOperations(rawOperations.records as RawOperation[], addr, accountId, 0)
412
+ )
415
413
  }
416
414
 
417
- return operations;
415
+ return operations
418
416
  } catch (e: unknown) {
419
417
  // FIXME: terrible hacks, because Stellar SDK fails to cast network failures to typed errors in react-native...
420
418
  // (https://github.com/stellar/js-stellar-sdk/issues/638)
421
- const errorMsg = e ? String(e) : "";
419
+ const errorMsg = e ? String(e) : ''
422
420
 
423
421
  if (e instanceof NotFoundError || errorMsg.match(/status code 404/)) {
424
- return [];
422
+ return []
425
423
  }
426
424
 
427
425
  if (errorMsg.match(/status code 4[0-9]{2}/)) {
428
- throw new LedgerAPI4xx();
426
+ throw new LedgerAPI4xx()
429
427
  }
430
428
 
431
429
  if (errorMsg.match(/status code 5[0-9]{2}/)) {
432
- throw new LedgerAPI5xx();
430
+ throw new LedgerAPI5xx()
433
431
  }
434
432
 
435
433
  if (
@@ -437,10 +435,10 @@ export async function fetchAllOperations(
437
435
  errorMsg.match(/ECONNRESET|ECONNREFUSED|ENOTFOUND|EPIPE|ETIMEDOUT/) ||
438
436
  errorMsg.match(/undefined is not an object/)
439
437
  ) {
440
- throw new NetworkDown();
438
+ throw new NetworkDown()
441
439
  }
442
440
 
443
- throw e;
441
+ throw e
444
442
  }
445
443
  }
446
444
 
@@ -453,19 +451,19 @@ export async function fetchOperations({
453
451
  cursor,
454
452
  limit,
455
453
  }: {
456
- accountId: string;
457
- addr: string;
458
- minHeight: number;
459
- order: "asc" | "desc";
460
- cursor: string | undefined;
461
- limit?: number | undefined;
454
+ accountId: string
455
+ addr: string
456
+ minHeight: number
457
+ order: 'asc' | 'desc'
458
+ cursor: string | undefined
459
+ limit?: number | undefined
462
460
  }): Promise<Page<Operation>> {
463
- const noResult: Page<Operation> = { items: [], next: "" };
461
+ const noResult: Page<Operation> = { items: [], next: '' }
464
462
  if (!addr) {
465
- return noResult;
463
+ return noResult
466
464
  }
467
465
 
468
- const requestedLimit = limit ?? coinConfig.getCoinConfig().explorer.fetchLimit ?? FETCH_LIMIT;
466
+ const requestedLimit = limit ?? coinConfig.getCoinConfig().explorer.fetchLimit ?? FETCH_LIMIT
469
467
 
470
468
  try {
471
469
  const rawOperations = await getServer()
@@ -473,41 +471,41 @@ export async function fetchOperations({
473
471
  .forAccount(addr)
474
472
  .limit(requestedLimit)
475
473
  .order(order)
476
- .cursor(cursor ?? "")
474
+ .cursor(cursor ?? '')
477
475
  .includeFailed(true)
478
- .join("transactions")
479
- .call();
476
+ .join('transactions')
477
+ .call()
480
478
 
481
479
  if (!rawOperations || !rawOperations.records.length) {
482
- return noResult;
480
+ return noResult
483
481
  }
484
482
 
485
- const rawOps = rawOperations.records as RawOperation[];
486
- const filteredOps = await rawOperationsToOperations(rawOps, addr, accountId, minHeight);
483
+ const rawOps = rawOperations.records as RawOperation[]
484
+ const filteredOps = await rawOperationsToOperations(rawOps, addr, accountId, minHeight)
487
485
 
488
486
  // Always return the cursor so the caller can continue pagination,
489
487
  // even when filteredOps is empty (e.g. page of unsupported types).
490
- const nextCursor = rawOps.length < requestedLimit ? "" : rawOps[rawOps.length - 1].paging_token;
488
+ const nextCursor = rawOps.length < requestedLimit ? '' : rawOps[rawOps.length - 1].paging_token
491
489
 
492
- return { items: filteredOps, next: nextCursor };
490
+ return { items: filteredOps, next: nextCursor }
493
491
  } catch (e: unknown) {
494
492
  // FIXME: terrible hacks, because Stellar SDK fails to cast network failures to typed errors in react-native...
495
493
  // (https://github.com/stellar/js-stellar-sdk/issues/638)
496
494
  // update 2025-04-01: in case of NetworkError, the error.response fields are undefined. Hence we cannot rely on status code
497
495
  // the only way to check is the errror message, which may break at some point
498
- const errorMsg = e ? String(e) : "";
496
+ const errorMsg = e ? String(e) : ''
499
497
 
500
498
  if (e instanceof NotFoundError || errorMsg.match(/status code 404/)) {
501
- return noResult;
499
+ return noResult
502
500
  }
503
501
  if (errorMsg.match(/too many requests/i)) {
504
- throw new LedgerAPI4xx("status code 4xx", { status: 429, url: undefined, method: "GET" });
502
+ throw new LedgerAPI4xx('status code 4xx', { status: 429, url: undefined, method: 'GET' })
505
503
  }
506
504
  if (errorMsg.match(/status code 4[0-9]{2}/)) {
507
- throw new LedgerAPI4xx();
505
+ throw new LedgerAPI4xx()
508
506
  }
509
507
  if (errorMsg.match(/status code 5[0-9]{2}/)) {
510
- throw new LedgerAPI5xx();
508
+ throw new LedgerAPI5xx()
511
509
  }
512
510
 
513
511
  if (
@@ -515,101 +513,101 @@ export async function fetchOperations({
515
513
  errorMsg.match(/ECONNRESET|ECONNREFUSED|ENOTFOUND|EPIPE|ETIMEDOUT/) ||
516
514
  errorMsg.match(/undefined is not an object/)
517
515
  ) {
518
- throw new NetworkDown();
516
+ throw new NetworkDown()
519
517
  }
520
518
 
521
- throw e;
519
+ throw e
522
520
  }
523
521
  }
524
522
 
525
523
  export async function fetchAccountNetworkInfo(account: string): Promise<NetworkInfo> {
526
524
  try {
527
- const extendedAccount = await getServer().accounts().accountId(account).call();
528
- const baseReserve = getReservedBalance(extendedAccount);
529
- const { recommendedFee, networkCongestionLevel, baseFee } = await fetchBaseFee();
525
+ const extendedAccount = await getServer().accounts().accountId(account).call()
526
+ const baseReserve = getReservedBalance(extendedAccount)
527
+ const { recommendedFee, networkCongestionLevel, baseFee } = await fetchBaseFee()
530
528
 
531
529
  return {
532
- family: "stellar",
530
+ family: 'stellar',
533
531
  fees: new BigNumber(recommendedFee.toString()),
534
532
  baseFee: new BigNumber(baseFee.toString()),
535
533
  baseReserve,
536
534
  networkCongestionLevel,
537
- };
535
+ }
538
536
  } catch {
539
537
  return {
540
- family: "stellar",
538
+ family: 'stellar',
541
539
  fees: new BigNumber(0),
542
540
  baseFee: new BigNumber(100),
543
541
  baseReserve: new BigNumber(0),
544
- };
542
+ }
545
543
  }
546
544
  }
547
545
 
548
546
  export async function fetchSequence(address: string): Promise<BigNumber> {
549
- const extendedAccount = await loadAccount(address);
550
- return extendedAccount ? new BigNumber(extendedAccount.sequence) : new BigNumber(0);
547
+ const extendedAccount = await loadAccount(address)
548
+ return extendedAccount ? new BigNumber(extendedAccount.sequence) : new BigNumber(0)
551
549
  }
552
550
 
553
551
  export async function fetchSigners(account: string): Promise<Signer[]> {
554
552
  try {
555
- const extendedAccount = await getServer().accounts().accountId(account).call();
556
- return extendedAccount.signers;
553
+ const extendedAccount = await getServer().accounts().accountId(account).call()
554
+ return extendedAccount.signers
557
555
  } catch {
558
- return [];
556
+ return []
559
557
  }
560
558
  }
561
559
 
562
560
  function interpretedError(error: unknown): unknown {
563
- const body = getHorizonBodyFromSubmitFailure(error);
561
+ const body = getHorizonBodyFromSubmitFailure(error)
564
562
  if (body) {
565
- const cause = error instanceof Error ? error : new Error(String(error));
566
- return makeBroadcastFailedError(body, cause);
563
+ const cause = error instanceof Error ? error : new Error(String(error))
564
+ return makeBroadcastFailedError(body, cause)
567
565
  }
568
- return error;
566
+ return error
569
567
  }
570
568
 
571
569
  export async function broadcastTransaction(signedTransaction: string): Promise<string> {
572
570
  try {
573
- patchHermesTypedArraysIfNeeded();
574
- const transaction = new StellarSdkTransaction(signedTransaction, Networks.PUBLIC);
571
+ patchHermesTypedArraysIfNeeded()
572
+ const transaction = new StellarSdkTransaction(signedTransaction, Networks.PUBLIC)
575
573
 
576
574
  try {
577
575
  const res = await getServer().submitTransaction(transaction, {
578
576
  skipMemoRequiredCheck: true,
579
- });
580
- return res.hash;
577
+ })
578
+ return res.hash
581
579
  } catch (error: unknown) {
582
- throw interpretedError(error);
580
+ throw interpretedError(error)
583
581
  }
584
582
  } finally {
585
583
  // Restore
586
- unpatchHermesTypedArrays();
584
+ unpatchHermesTypedArrays()
587
585
  }
588
586
  }
589
587
 
590
588
  export async function loadAccount(addr: string): Promise<Horizon.AccountResponse | null> {
591
589
  if (!addr || !addr.length) {
592
- return null;
590
+ return null
593
591
  }
594
592
 
595
593
  try {
596
- return await getServer().loadAccount(addr);
594
+ return await getServer().loadAccount(addr)
597
595
  } catch {
598
- return null;
596
+ return null
599
597
  }
600
598
  }
601
599
 
602
600
  export async function getLastBlock(): Promise<{
603
- height: number;
604
- hash: string;
605
- time: Date;
601
+ height: number
602
+ hash: string
603
+ time: Date
606
604
  }> {
607
- const ledger = await getServer().ledgers().order("desc").limit(1).call();
605
+ const ledger = await getServer().ledgers().order('desc').limit(1).call()
608
606
  return {
609
607
  height: ledger.records[0].sequence,
610
608
  hash: ledger.records[0].hash,
611
609
  time: new Date(ledger.records[0].closed_at),
612
- };
610
+ }
613
611
  }
614
612
 
615
613
  /**
@@ -622,11 +620,11 @@ export async function getLastBlock(): Promise<{
622
620
  */
623
621
  export async function fetchLedgerRecord(sequence: number): Promise<Horizon.ServerApi.LedgerRecord> {
624
622
  try {
625
- const record = await getServer().ledgers().ledger(sequence).call();
623
+ const record = await getServer().ledgers().ledger(sequence).call()
626
624
  // Horizon returns a single ledger; SDK typings still use CollectionPage for this builder.
627
- return record as unknown as Horizon.ServerApi.LedgerRecord;
625
+ return record as unknown as Horizon.ServerApi.LedgerRecord
628
626
  } catch (e: unknown) {
629
- throwHorizonLedgerOrOperationsError(e, `Stellar ledger ${sequence} not found`);
627
+ throwHorizonLedgerOrOperationsError(e, `Stellar ledger ${sequence} not found`)
630
628
  }
631
629
  }
632
630
 
@@ -637,95 +635,95 @@ export async function fetchLedgerRecord(sequence: number): Promise<Horizon.Serve
637
635
  * @throws Error when the ledger does not exist (Horizon 404).
638
636
  */
639
637
  export async function fetchAllLedgerOperations(ledgerSequence: number): Promise<RawOperation[]> {
640
- const limit = coinConfig.getCoinConfig().explorer.fetchLimit ?? FETCH_LIMIT;
638
+ const limit = coinConfig.getCoinConfig().explorer.fetchLimit ?? FETCH_LIMIT
641
639
 
642
640
  try {
643
641
  let response = await getServer()
644
642
  .operations()
645
643
  .forLedger(ledgerSequence)
646
644
  .includeFailed(true)
647
- .join("transactions")
648
- .order("asc")
645
+ .join('transactions')
646
+ .order('asc')
649
647
  .limit(limit)
650
- .call();
648
+ .call()
651
649
 
652
- const records: RawOperation[] = [...(response.records as RawOperation[])];
650
+ const records: RawOperation[] = [...(response.records as RawOperation[])]
653
651
 
654
652
  while (response.records.length === limit) {
655
- response = await response.next();
656
- records.push(...(response.records as RawOperation[]));
653
+ response = await response.next()
654
+ records.push(...(response.records as RawOperation[]))
657
655
  if (response.records.length === 0) {
658
- break;
656
+ break
659
657
  }
660
658
  }
661
659
 
662
- return records;
660
+ return records
663
661
  } catch (e: unknown) {
664
- throwHorizonLedgerOrOperationsError(e, `Stellar ledger ${ledgerSequence} not found`);
662
+ throwHorizonLedgerOrOperationsError(e, `Stellar ledger ${ledgerSequence} not found`)
665
663
  }
666
664
  }
667
665
 
668
666
  export const getRecipientAccount: CacheRes<
669
667
  Array<{
670
- recipient: string;
668
+ recipient: string
671
669
  }>,
672
670
  {
673
- id: string | null;
674
- isMuxedAccount: boolean;
675
- assetIds: string[];
671
+ id: string | null
672
+ isMuxedAccount: boolean
673
+ assetIds: string[]
676
674
  } | null
677
675
  > = makeLRUCache(
678
676
  async ({ recipient }) => await recipientAccount(recipient),
679
- extract => extract.recipient,
677
+ (extract) => extract.recipient,
680
678
  {
681
679
  max: 300,
682
680
  ttl: 5 * 60,
683
- }, // 5 minutes
684
- );
681
+ } // 5 minutes
682
+ )
685
683
 
686
684
  async function recipientAccount(address?: string): Promise<{
687
- id: string | null;
688
- isMuxedAccount: boolean;
689
- assetIds: string[];
685
+ id: string | null
686
+ isMuxedAccount: boolean
687
+ assetIds: string[]
690
688
  } | null> {
691
689
  if (!address) {
692
- return null;
690
+ return null
693
691
  }
694
692
 
695
- let accountAddress = address;
693
+ let accountAddress = address
696
694
 
697
- const isMuxedAccount = StrKey.isValidMed25519PublicKey(address);
695
+ const isMuxedAccount = StrKey.isValidMed25519PublicKey(address)
698
696
 
699
697
  if (isMuxedAccount) {
700
- const muxedAccount = MuxedAccount.fromAddress(address, "0");
701
- accountAddress = muxedAccount.baseAccount().accountId();
698
+ const muxedAccount = MuxedAccount.fromAddress(address, '0')
699
+ accountAddress = muxedAccount.baseAccount().accountId()
702
700
  }
703
701
 
704
- const account: Horizon.AccountResponse | null = await loadAccount(accountAddress);
702
+ const account: Horizon.AccountResponse | null = await loadAccount(accountAddress)
705
703
 
706
704
  if (!account) {
707
- return null;
705
+ return null
708
706
  }
709
707
 
710
708
  return {
711
709
  id: account.id,
712
710
  isMuxedAccount,
713
711
  assetIds: account.balances.reduce((allAssets: any[], balance: any) => {
714
- return [...allAssets, getBalanceId(balance)];
712
+ return [...allAssets, getBalanceId(balance)]
715
713
  }, []),
716
- };
714
+ }
717
715
  }
718
716
 
719
717
  function getBalanceId(balance: BalanceAsset): string | null {
720
718
  switch (balance.asset_type) {
721
- case "native":
722
- return "native";
723
- case "liquidity_pool_shares":
724
- return balance.liquidity_pool_id || null;
725
- case "credit_alphanum4":
726
- case "credit_alphanum12":
727
- return `${balance.asset_code}:${balance.asset_issuer}`;
719
+ case 'native':
720
+ return 'native'
721
+ case 'liquidity_pool_shares':
722
+ return balance.liquidity_pool_id || null
723
+ case 'credit_alphanum4':
724
+ case 'credit_alphanum12':
725
+ return `${balance.asset_code}:${balance.asset_issuer}`
728
726
  default:
729
- return null;
727
+ return null
730
728
  }
731
729
  }