perp-cli 0.12.17 → 0.14.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 (363) hide show
  1. package/README.md +247 -27
  2. package/dist/_stderr-filter.js +0 -1
  3. package/dist/agent-wallet/lighter-keystore.d.ts +11 -0
  4. package/dist/agent-wallet/lighter-keystore.js +92 -10
  5. package/dist/agent-wallet/passphrase.d.ts +1 -1
  6. package/dist/agent-wallet/passphrase.js +16 -3
  7. package/dist/agent-wallet/store.d.ts +37 -4
  8. package/dist/agent-wallet/store.js +132 -0
  9. package/dist/agent-wallet/venue-keystore.d.ts +14 -0
  10. package/dist/agent-wallet/venue-keystore.js +121 -0
  11. package/dist/api/public/hyperliquid.js +4 -4
  12. package/dist/api/public/lighter.js +5 -5
  13. package/dist/api/public/pacifica.d.ts +0 -1
  14. package/dist/api/public/pacifica.js +4 -13
  15. package/dist/api/public/urls.d.ts +9 -1
  16. package/dist/api/public/urls.js +35 -13
  17. package/dist/arb/file-lock.d.ts +11 -0
  18. package/dist/arb/file-lock.js +74 -0
  19. package/dist/arb/index.d.ts +2 -2
  20. package/dist/arb/index.js +2 -2
  21. package/dist/arb/pending-entry.d.ts +32 -0
  22. package/dist/arb/pending-entry.js +77 -0
  23. package/dist/arb/sizing.d.ts +6 -13
  24. package/dist/arb/sizing.js +12 -51
  25. package/dist/arb/state.d.ts +45 -12
  26. package/dist/arb/state.js +214 -42
  27. package/dist/arb/utils.d.ts +20 -6
  28. package/dist/arb/utils.js +43 -39
  29. package/dist/bot/conditions.d.ts +4 -4
  30. package/dist/bot/conditions.js +11 -6
  31. package/dist/bot/config.d.ts +17 -1
  32. package/dist/bot/config.js +48 -12
  33. package/dist/bot/engine.d.ts +61 -2
  34. package/dist/bot/engine.js +610 -144
  35. package/dist/bot/fill-size.d.ts +7 -0
  36. package/dist/bot/fill-size.js +18 -0
  37. package/dist/bot/index.d.ts +1 -1
  38. package/dist/bot/index.js +1 -1
  39. package/dist/bot/perp-order.d.ts +99 -0
  40. package/dist/bot/perp-order.js +299 -0
  41. package/dist/bot/presets.d.ts +7 -0
  42. package/dist/bot/presets.js +17 -0
  43. package/dist/bot/quarantine.d.ts +75 -0
  44. package/dist/bot/quarantine.js +190 -0
  45. package/dist/bot/quote-rules.d.ts +23 -0
  46. package/dist/bot/quote-rules.js +69 -0
  47. package/dist/bot/strategies/avellaneda-mm.d.ts +32 -2
  48. package/dist/bot/strategies/avellaneda-mm.js +72 -70
  49. package/dist/bot/strategies/basis-arb.js +2 -0
  50. package/dist/bot/strategies/dca-strategy.d.ts +2 -0
  51. package/dist/bot/strategies/dca-strategy.js +5 -0
  52. package/dist/bot/strategies/funding-arb-strategy.d.ts +43 -3
  53. package/dist/bot/strategies/funding-arb-strategy.js +571 -380
  54. package/dist/bot/strategies/funding-arb-utils.d.ts +48 -23
  55. package/dist/bot/strategies/funding-arb-utils.js +159 -195
  56. package/dist/bot/strategies/funding-arb-v2.d.ts +32 -0
  57. package/dist/bot/strategies/funding-arb-v2.js +258 -47
  58. package/dist/bot/strategies/funding-auto.js +215 -194
  59. package/dist/bot/strategies/spot-perp-arb-strategy.d.ts +14 -0
  60. package/dist/bot/strategies/spot-perp-arb-strategy.js +217 -50
  61. package/dist/bot/strategies/spot-perp-executor.d.ts +73 -19
  62. package/dist/bot/strategies/spot-perp-executor.js +319 -120
  63. package/dist/bot/strategies/spot-perp-state.d.ts +43 -0
  64. package/dist/bot/strategies/spot-perp-state.js +70 -0
  65. package/dist/bot/strategy-types.d.ts +6 -0
  66. package/dist/bot/tui/BotDashboard.d.ts +7 -2
  67. package/dist/bot/tui/BotDashboard.js +6 -3
  68. package/dist/bridge-engine.d.ts +120 -19
  69. package/dist/bridge-engine.js +710 -422
  70. package/dist/bridge-signers.d.ts +54 -0
  71. package/dist/bridge-signers.js +161 -0
  72. package/dist/cache.d.ts +4 -1
  73. package/dist/cache.js +11 -0
  74. package/dist/cli-flags.d.ts +50 -0
  75. package/dist/cli-flags.js +104 -0
  76. package/dist/cli-program.d.ts +35 -0
  77. package/dist/cli-program.js +303 -0
  78. package/dist/cli-spec.js +1 -1
  79. package/dist/client-id-tracker.js +11 -2
  80. package/dist/commands/account.d.ts +7 -1
  81. package/dist/commands/account.js +70 -92
  82. package/dist/commands/agent-import.d.ts +114 -0
  83. package/dist/commands/agent-import.js +794 -0
  84. package/dist/commands/agent.d.ts +232 -2
  85. package/dist/commands/agent.js +1858 -955
  86. package/dist/commands/alerts.d.ts +1 -0
  87. package/dist/commands/alerts.js +31 -28
  88. package/dist/commands/arb/index.d.ts +60 -1
  89. package/dist/commands/arb/index.js +381 -384
  90. package/dist/commands/arb-auto.d.ts +132 -4
  91. package/dist/commands/arb-auto.js +1474 -967
  92. package/dist/commands/arb.d.ts +3 -1
  93. package/dist/commands/arb.js +62 -30
  94. package/dist/commands/bot.js +127 -47
  95. package/dist/commands/bridge.d.ts +2 -1
  96. package/dist/commands/bridge.js +339 -192
  97. package/dist/commands/builder.d.ts +55 -0
  98. package/dist/commands/builder.js +387 -0
  99. package/dist/commands/funds-onchain.d.ts +32 -0
  100. package/dist/commands/funds-onchain.js +248 -0
  101. package/dist/commands/funds.d.ts +25 -0
  102. package/dist/commands/funds.js +925 -245
  103. package/dist/commands/history.js +102 -54
  104. package/dist/commands/init.d.ts +107 -15
  105. package/dist/commands/init.js +1116 -249
  106. package/dist/commands/jobs.d.ts +2 -1
  107. package/dist/commands/jobs.js +77 -15
  108. package/dist/commands/manage.js +136 -91
  109. package/dist/commands/market.d.ts +4 -1
  110. package/dist/commands/market.js +35 -32
  111. package/dist/commands/outcome.d.ts +10 -0
  112. package/dist/commands/outcome.js +396 -0
  113. package/dist/commands/plan.js +52 -12
  114. package/dist/commands/portfolio.d.ts +1 -0
  115. package/dist/commands/portfolio.js +60 -72
  116. package/dist/commands/rebalance.d.ts +2 -1
  117. package/dist/commands/rebalance.js +33 -43
  118. package/dist/commands/risk.js +46 -19
  119. package/dist/commands/settings.d.ts +1 -0
  120. package/dist/commands/settings.js +246 -51
  121. package/dist/commands/trade.d.ts +50 -0
  122. package/dist/commands/trade.js +1943 -695
  123. package/dist/commands/wallet.d.ts +30 -1
  124. package/dist/commands/wallet.js +357 -459
  125. package/dist/config.d.ts +60 -9
  126. package/dist/config.js +252 -82
  127. package/dist/constants.d.ts +29 -4
  128. package/dist/constants.js +62 -20
  129. package/dist/dashboard/server.d.ts +2 -0
  130. package/dist/dashboard/server.js +9 -6
  131. package/dist/dashboard/ui.js +6 -4
  132. package/dist/dashboard/ws-feeds.js +20 -8
  133. package/dist/dex-asset-map.js +5 -3
  134. package/dist/errors.d.ts +122 -0
  135. package/dist/errors.js +194 -0
  136. package/dist/event-stream.js +75 -19
  137. package/dist/evm-master-tx.d.ts +59 -0
  138. package/dist/evm-master-tx.js +154 -0
  139. package/dist/exchanges/adapter-network.d.ts +10 -0
  140. package/dist/exchanges/adapter-network.js +10 -0
  141. package/dist/exchanges/arcus/adapter.d.ts +196 -0
  142. package/dist/exchanges/arcus/adapter.js +1092 -0
  143. package/dist/exchanges/arcus/agent.d.ts +55 -0
  144. package/dist/exchanges/arcus/agent.js +188 -0
  145. package/dist/exchanges/arcus/client.d.ts +63 -0
  146. package/dist/exchanges/arcus/client.js +285 -0
  147. package/dist/exchanges/arcus/public.d.ts +65 -0
  148. package/dist/exchanges/arcus/public.js +138 -0
  149. package/dist/exchanges/arcus/signing.d.ts +176 -0
  150. package/dist/exchanges/arcus/signing.js +288 -0
  151. package/dist/exchanges/arcus/spot-chain.d.ts +60 -0
  152. package/dist/exchanges/arcus/spot-chain.js +241 -0
  153. package/dist/exchanges/arcus/spot-router.d.ts +177 -0
  154. package/dist/exchanges/arcus/spot-router.js +183 -0
  155. package/dist/exchanges/arcus/spot.d.ts +109 -0
  156. package/dist/exchanges/arcus/spot.js +645 -0
  157. package/dist/exchanges/aster-funds.d.ts +127 -0
  158. package/dist/exchanges/aster-funds.js +252 -0
  159. package/dist/exchanges/aster-nonce.d.ts +2 -0
  160. package/dist/exchanges/aster-nonce.js +107 -0
  161. package/dist/exchanges/aster-spot.d.ts +117 -0
  162. package/dist/exchanges/aster-spot.js +686 -0
  163. package/dist/exchanges/aster-typed-data.d.ts +133 -7
  164. package/dist/exchanges/aster-typed-data.js +121 -7
  165. package/dist/exchanges/aster.d.ts +240 -6
  166. package/dist/exchanges/aster.js +1139 -195
  167. package/dist/exchanges/builder-fee.d.ts +254 -0
  168. package/dist/exchanges/builder-fee.js +421 -0
  169. package/dist/exchanges/canonical-symbols.d.ts +32 -0
  170. package/dist/exchanges/canonical-symbols.js +96 -0
  171. package/dist/exchanges/capabilities.d.ts +7 -1
  172. package/dist/exchanges/capabilities.js +7 -0
  173. package/dist/exchanges/hl-signing.d.ts +165 -0
  174. package/dist/exchanges/hl-signing.js +158 -0
  175. package/dist/exchanges/hyperliquid-outcome.d.ts +211 -0
  176. package/dist/exchanges/hyperliquid-outcome.js +646 -0
  177. package/dist/exchanges/hyperliquid-spot.d.ts +44 -5
  178. package/dist/exchanges/hyperliquid-spot.js +308 -117
  179. package/dist/exchanges/hyperliquid.d.ts +462 -57
  180. package/dist/exchanges/hyperliquid.js +1575 -449
  181. package/dist/exchanges/index.d.ts +6 -0
  182. package/dist/exchanges/index.js +4 -0
  183. package/dist/exchanges/interface.d.ts +63 -10
  184. package/dist/exchanges/interface.js +18 -3
  185. package/dist/exchanges/ioc-outcome.d.ts +44 -0
  186. package/dist/exchanges/ioc-outcome.js +57 -0
  187. package/dist/exchanges/legacy-trading-v2.d.ts +39 -0
  188. package/dist/exchanges/legacy-trading-v2.js +940 -0
  189. package/dist/exchanges/lighter-public.d.ts +43 -0
  190. package/dist/exchanges/lighter-public.js +276 -0
  191. package/dist/exchanges/lighter-rh-deposit.d.ts +62 -0
  192. package/dist/exchanges/lighter-rh-deposit.js +185 -0
  193. package/dist/exchanges/lighter-signer.d.ts +123 -0
  194. package/dist/exchanges/lighter-signer.js +215 -0
  195. package/dist/exchanges/lighter-spot.d.ts +91 -13
  196. package/dist/exchanges/lighter-spot.js +595 -233
  197. package/dist/exchanges/lighter.d.ts +611 -39
  198. package/dist/exchanges/lighter.js +1890 -649
  199. package/dist/exchanges/ondo/adapter.d.ts +152 -0
  200. package/dist/exchanges/ondo/adapter.js +811 -0
  201. package/dist/exchanges/ondo/agent.d.ts +31 -0
  202. package/dist/exchanges/ondo/agent.js +101 -0
  203. package/dist/exchanges/ondo/client.d.ts +60 -0
  204. package/dist/exchanges/ondo/client.js +297 -0
  205. package/dist/exchanges/ondo/funds.d.ts +95 -0
  206. package/dist/exchanges/ondo/funds.js +198 -0
  207. package/dist/exchanges/ondo/public.d.ts +95 -0
  208. package/dist/exchanges/ondo/public.js +214 -0
  209. package/dist/exchanges/ondo/spot.d.ts +127 -0
  210. package/dist/exchanges/ondo/spot.js +392 -0
  211. package/dist/exchanges/outcome-interface.d.ts +140 -0
  212. package/dist/exchanges/outcome-interface.js +16 -0
  213. package/dist/exchanges/pacifica-spot.d.ts +83 -0
  214. package/dist/exchanges/pacifica-spot.js +324 -0
  215. package/dist/exchanges/pacifica-typed-data.d.ts +30 -13
  216. package/dist/exchanges/pacifica-typed-data.js +57 -9
  217. package/dist/exchanges/pacifica.d.ts +293 -4
  218. package/dist/exchanges/pacifica.js +1044 -90
  219. package/dist/exchanges/precision.d.ts +47 -0
  220. package/dist/exchanges/precision.js +209 -0
  221. package/dist/exchanges/qfex/adapter.d.ts +341 -0
  222. package/dist/exchanges/qfex/adapter.js +1386 -0
  223. package/dist/exchanges/qfex/agent.d.ts +58 -0
  224. package/dist/exchanges/qfex/agent.js +188 -0
  225. package/dist/exchanges/qfex/client.d.ts +54 -0
  226. package/dist/exchanges/qfex/client.js +138 -0
  227. package/dist/exchanges/qfex/errors.d.ts +70 -0
  228. package/dist/exchanges/qfex/errors.js +236 -0
  229. package/dist/exchanges/qfex/public.d.ts +122 -0
  230. package/dist/exchanges/qfex/public.js +268 -0
  231. package/dist/exchanges/qfex/signing.d.ts +160 -0
  232. package/dist/exchanges/qfex/signing.js +283 -0
  233. package/dist/exchanges/qfex/ws-transport.d.ts +294 -0
  234. package/dist/exchanges/qfex/ws-transport.js +798 -0
  235. package/dist/exchanges/rate-limiter.d.ts +12 -0
  236. package/dist/exchanges/rate-limiter.js +64 -0
  237. package/dist/exchanges/registry.d.ts +14 -2
  238. package/dist/exchanges/registry.js +20 -32
  239. package/dist/exchanges/slippage.d.ts +37 -0
  240. package/dist/exchanges/slippage.js +70 -0
  241. package/dist/exchanges/spot-factory.d.ts +166 -0
  242. package/dist/exchanges/spot-factory.js +431 -0
  243. package/dist/exchanges/spot-interface.d.ts +98 -4
  244. package/dist/exchanges/spot-interface.js +27 -1
  245. package/dist/exchanges/spot-result.d.ts +79 -0
  246. package/dist/exchanges/spot-result.js +273 -0
  247. package/dist/exchanges/trading-v2.d.ts +117 -0
  248. package/dist/exchanges/trading-v2.js +301 -0
  249. package/dist/exchanges/venue-types.d.ts +231 -0
  250. package/dist/exchanges/venue-types.js +87 -0
  251. package/dist/exchanges/venue.d.ts +211 -0
  252. package/dist/exchanges/venue.js +132 -0
  253. package/dist/exchanges/venues/arcus.d.ts +8 -0
  254. package/dist/exchanges/venues/arcus.js +109 -0
  255. package/dist/exchanges/venues/aster.d.ts +49 -0
  256. package/dist/exchanges/venues/aster.js +176 -0
  257. package/dist/exchanges/venues/create-helpers.d.ts +18 -0
  258. package/dist/exchanges/venues/create-helpers.js +199 -0
  259. package/dist/exchanges/venues/hyperliquid.d.ts +23 -0
  260. package/dist/exchanges/venues/hyperliquid.js +126 -0
  261. package/dist/exchanges/venues/index.d.ts +16 -0
  262. package/dist/exchanges/venues/index.js +26 -0
  263. package/dist/exchanges/venues/lighter-family.d.ts +92 -0
  264. package/dist/exchanges/venues/lighter-family.js +166 -0
  265. package/dist/exchanges/venues/lighter-rh.d.ts +7 -0
  266. package/dist/exchanges/venues/lighter-rh.js +58 -0
  267. package/dist/exchanges/venues/lighter.d.ts +6 -0
  268. package/dist/exchanges/venues/lighter.js +55 -0
  269. package/dist/exchanges/venues/ondo.d.ts +29 -0
  270. package/dist/exchanges/venues/ondo.js +136 -0
  271. package/dist/exchanges/venues/pacifica.d.ts +8 -0
  272. package/dist/exchanges/venues/pacifica.js +95 -0
  273. package/dist/exchanges/venues/qfex.d.ts +39 -0
  274. package/dist/exchanges/venues/qfex.js +140 -0
  275. package/dist/execution-log.js +10 -2
  276. package/dist/funding/legacy-public.d.ts +31 -0
  277. package/dist/funding/legacy-public.js +369 -0
  278. package/dist/funding/normalize.d.ts +28 -16
  279. package/dist/funding/normalize.js +61 -29
  280. package/dist/funding/rates.d.ts +46 -11
  281. package/dist/funding/rates.js +228 -277
  282. package/dist/guardrail/perp-guardrail.js +0 -0
  283. package/dist/index.js +156 -684
  284. package/dist/jobs.d.ts +84 -6
  285. package/dist/jobs.js +239 -41
  286. package/dist/landing.d.ts +7 -2
  287. package/dist/landing.js +19 -3
  288. package/dist/mcp-server.d.ts +14 -4
  289. package/dist/mcp-server.js +821 -403
  290. package/dist/mcp-trade-guard.d.ts +16 -0
  291. package/dist/mcp-trade-guard.js +59 -0
  292. package/dist/onchain-balances.d.ts +40 -0
  293. package/dist/onchain-balances.js +173 -0
  294. package/dist/pacifica/client.d.ts +41 -10
  295. package/dist/pacifica/client.js +167 -63
  296. package/dist/pacifica/constants.d.ts +0 -1
  297. package/dist/pacifica/constants.js +0 -5
  298. package/dist/pacifica/deposit.d.ts +30 -3
  299. package/dist/pacifica/deposit.js +119 -2
  300. package/dist/pacifica/faucet.d.ts +29 -0
  301. package/dist/pacifica/faucet.js +100 -0
  302. package/dist/pacifica/sign-tx.d.ts +15 -0
  303. package/dist/pacifica/sign-tx.js +41 -0
  304. package/dist/pacifica/types/account.d.ts +28 -4
  305. package/dist/pacifica/types/lake.d.ts +20 -5
  306. package/dist/pacifica/types/lake.js +4 -0
  307. package/dist/pacifica/types/market.d.ts +5 -0
  308. package/dist/pacifica/types/order.d.ts +4 -1
  309. package/dist/pacifica/types/position.d.ts +9 -1
  310. package/dist/plan-executor.d.ts +10 -5
  311. package/dist/plan-executor.js +165 -54
  312. package/dist/position-history.js +13 -0
  313. package/dist/rebalance.d.ts +26 -2
  314. package/dist/rebalance.js +86 -7
  315. package/dist/relay-swap.d.ts +232 -0
  316. package/dist/relay-swap.js +630 -0
  317. package/dist/risk.js +5 -1
  318. package/dist/secret-env.d.ts +15 -0
  319. package/dist/secret-env.js +36 -0
  320. package/dist/settings.d.ts +169 -6
  321. package/dist/settings.js +219 -38
  322. package/dist/signer/ows-evm.d.ts +13 -0
  323. package/dist/signer/ows-evm.js +22 -0
  324. package/dist/smart-order.d.ts +9 -0
  325. package/dist/smart-order.js +53 -8
  326. package/dist/strategies/dca.d.ts +6 -2
  327. package/dist/strategies/dca.js +66 -26
  328. package/dist/strategies/funding-arb.d.ts +11 -1
  329. package/dist/strategies/funding-arb.js +202 -89
  330. package/dist/strategies/grid.d.ts +31 -0
  331. package/dist/strategies/grid.js +89 -11
  332. package/dist/strategies/pending-stop.d.ts +8 -0
  333. package/dist/strategies/pending-stop.js +12 -0
  334. package/dist/strategies/split-order.d.ts +45 -17
  335. package/dist/strategies/split-order.js +157 -91
  336. package/dist/strategies/trailing-stop.d.ts +2 -1
  337. package/dist/strategies/trailing-stop.js +52 -6
  338. package/dist/strategies/twap.d.ts +6 -1
  339. package/dist/strategies/twap.js +39 -11
  340. package/dist/trade-validator.d.ts +22 -0
  341. package/dist/trade-validator.js +119 -15
  342. package/dist/utils/numeric.d.ts +46 -0
  343. package/dist/utils/numeric.js +79 -0
  344. package/dist/utils.d.ts +19 -0
  345. package/dist/utils.js +96 -19
  346. package/dist/withdraw-gate.d.ts +49 -0
  347. package/dist/withdraw-gate.js +131 -0
  348. package/package.json +15 -6
  349. package/skills/perp-cli/SKILL.md +159 -55
  350. package/skills/perp-cli/references/agent-operations.md +112 -58
  351. package/skills/perp-cli/references/commands.md +269 -73
  352. package/skills/perp-cli/references/strategies.md +34 -31
  353. package/skills/perp-cli/scripts/arb-monitor.sh +10 -5
  354. package/skills/perp-cli/scripts/funding-analysis.sh +14 -9
  355. package/skills/perp-cli/scripts/preflight.sh +21 -14
  356. package/skills/perp-cli/scripts/spot-perp-scan.sh +12 -7
  357. package/skills/perp-cli/scripts/validate-arb.sh +31 -15
  358. package/vendor/lighter-signer/SHA256SUMS +2 -0
  359. package/vendor/lighter-signer/VERSION +8 -0
  360. package/vendor/lighter-signer/lighter-signer.wasm +0 -0
  361. package/vendor/lighter-signer/wasm_exec.js +575 -0
  362. package/dist/bot/strategies/funding-arb-v2-strategy.d.ts +0 -42
  363. package/dist/bot/strategies/funding-arb-v2-strategy.js +0 -864
@@ -1,26 +1,36 @@
1
1
  /**
2
- * Funding rate normalization.
2
+ * Funding rate normalization (design §10.1, §10.13 #1).
3
3
  *
4
- * Exchange funding rate periods:
5
- * - Hyperliquid: per 1 HOUR (settles every 1h)
6
- * - Pacifica: per 1 HOUR (settles every 1h)
7
- * - Lighter: per 8 HOURS (API returns 8h rate, settles every 1h)
4
+ * The number of hours one quoted rate covers (the funding BASIS) comes from the
5
+ * venue definition — `VenueDefinition.fundingRateBasis`, read through
6
+ * `fundingBasisOf(ref)`. Settlement timing is a separate concept (arb/utils.ts).
8
7
  *
9
- * HIP-3 deployed dexes on Hyperliquid use 8h funding periods.
10
- *
11
- * To compare rates across exchanges, we normalize everything to
12
- * a per-hour basis, then annualize from there.
8
+ * A venue ref is a venue id/alias, or "hl:<dex>" for Hyperliquid HIP-3 dexes
9
+ * (those resolve to the Hyperliquid core basis — current behavior preserved).
10
+ * Unknown refs throw UNKNOWN_VENUE; per-market venues
11
+ * have no single hours value — use the market's basis with the `*ByBasis`
12
+ * variants below.
13
+ */
14
+ import { type FundingRateBasis } from "../exchanges/venue-types.js";
15
+ /**
16
+ * Funding basis of a venue ref. Unknown refs (e.g. a stale value in persisted
17
+ * arb/bot state) surface as UNKNOWN_VENUE with remediation instead of an
18
+ * anonymous crash deep inside a strategy loop.
13
19
  */
20
+ export declare function venueFundingBasis(ref: string): FundingRateBasis;
14
21
  /**
15
- * Get funding period in hours for an exchange.
16
- * HIP-3 deployed dexes (not in the map) default to 1h (API returns hourly).
17
- * HL and PAC are 1h, Lighter API returns 8h rates.
22
+ * Hours one quoted funding rate covers for a venue ref.
23
+ * Throws INVALID_PARAMS for per-market or annualized venues — use the market's basis.
18
24
  */
19
- export declare function getFundingHours(exchange: string): number;
20
- /** Convert a raw funding rate to per-hour rate */
21
- export declare function toHourlyRate(rate: number, exchange: string): number;
25
+ export declare function getFundingHours(ref: string): number;
26
+ /** Convert a raw quoted rate to a per-hour rate using an explicit (market) basis. */
27
+ export declare function toHourlyRateByBasis(rate: number, basis: FundingRateBasis): number;
28
+ /** Convert a raw funding rate to per-hour rate using the venue's basis. */
29
+ export declare function toHourlyRate(rate: number, ref: string): number;
22
30
  /** Annualize a raw rate from a specific exchange */
23
31
  export declare function annualizeRate(rate: number, exchange: string): number;
32
+ /** Annualize a raw rate quoted on an explicit (market) basis */
33
+ export declare function annualizeRateByBasis(rate: number, basis: FundingRateBasis): number;
24
34
  /** Annualize an already-normalized hourly rate (no exchange conversion needed) */
25
35
  export declare function annualizeHourlyRate(hourlyRate: number): number;
26
36
  /**
@@ -39,9 +49,11 @@ export declare function computeSignedAnnualSpread(shortRate: number, shortExchan
39
49
  /**
40
50
  * Estimate hourly funding payment for a position.
41
51
  * @param rate - raw funding rate from the exchange
42
- * @param exchange - exchange name
52
+ * @param exchange - venue ref
43
53
  * @param positionUsd - position notional in USD
44
54
  * @param side - "long" or "short" (longs pay positive rate, shorts receive)
45
55
  * @returns hourly payment in USD (positive = you pay, negative = you receive)
46
56
  */
47
57
  export declare function estimateHourlyFunding(rate: number, exchange: string, positionUsd: number, side: "long" | "short"): number;
58
+ /** Same as estimateHourlyFunding, from an already-normalized hourly rate. */
59
+ export declare function estimateHourlyFundingFromHourly(hourlyRate: number, positionUsd: number, side: "long" | "short"): number;
@@ -1,42 +1,71 @@
1
1
  /**
2
- * Funding rate normalization.
2
+ * Funding rate normalization (design §10.1, §10.13 #1).
3
3
  *
4
- * Exchange funding rate periods:
5
- * - Hyperliquid: per 1 HOUR (settles every 1h)
6
- * - Pacifica: per 1 HOUR (settles every 1h)
7
- * - Lighter: per 8 HOURS (API returns 8h rate, settles every 1h)
4
+ * The number of hours one quoted rate covers (the funding BASIS) comes from the
5
+ * venue definition — `VenueDefinition.fundingRateBasis`, read through
6
+ * `fundingBasisOf(ref)`. Settlement timing is a separate concept (arb/utils.ts).
8
7
  *
9
- * HIP-3 deployed dexes on Hyperliquid use 8h funding periods.
10
- *
11
- * To compare rates across exchanges, we normalize everything to
12
- * a per-hour basis, then annualize from there.
8
+ * A venue ref is a venue id/alias, or "hl:<dex>" for Hyperliquid HIP-3 dexes
9
+ * (those resolve to the Hyperliquid core basis — current behavior preserved).
10
+ * Unknown refs throw UNKNOWN_VENUE; per-market venues
11
+ * have no single hours value — use the market's basis with the `*ByBasis`
12
+ * variants below.
13
13
  */
14
+ import { PerpError } from "../errors.js";
15
+ import { fundingBasisOf, parseVenueRef } from "../exchanges/venue.js";
16
+ import { rateToHourly } from "../exchanges/venue-types.js";
17
+ import { ensureVenuesRegistered } from "../exchanges/venues/index.js";
14
18
  /** Funding periods per year by convention */
15
19
  const HOURLY_PERIODS = 24 * 365; // 8760
16
- /** How many hours each exchange's rate covers */
17
- const EXCHANGE_FUNDING_HOURS = {
18
- hyperliquid: 1,
19
- pacifica: 1,
20
- lighter: 8,
21
- aster: 8,
22
- };
23
20
  /**
24
- * Get funding period in hours for an exchange.
25
- * HIP-3 deployed dexes (not in the map) default to 1h (API returns hourly).
26
- * HL and PAC are 1h, Lighter API returns 8h rates.
21
+ * Funding basis of a venue ref. Unknown refs (e.g. a stale value in persisted
22
+ * arb/bot state) surface as UNKNOWN_VENUE with remediation instead of an
23
+ * anonymous crash deep inside a strategy loop.
24
+ */
25
+ export function venueFundingBasis(ref) {
26
+ ensureVenuesRegistered();
27
+ try {
28
+ parseVenueRef(ref);
29
+ }
30
+ catch (err) {
31
+ if (err instanceof PerpError && err.structured.code === "UNKNOWN_VENUE") {
32
+ throw new PerpError("UNKNOWN_VENUE", `Cannot normalize funding for unknown venue reference "${ref}"`, {
33
+ remediation: "Use a registered venue id (or hl:<dex> for HIP-3). If the value came from persisted state "
34
+ + "(~/.perp/arb-state.json or a bot state file), fix or remove that entry.",
35
+ });
36
+ }
37
+ throw err;
38
+ }
39
+ return fundingBasisOf(ref);
40
+ }
41
+ /**
42
+ * Hours one quoted funding rate covers for a venue ref.
43
+ * Throws INVALID_PARAMS for per-market or annualized venues — use the market's basis.
27
44
  */
28
- export function getFundingHours(exchange) {
29
- return EXCHANGE_FUNDING_HOURS[exchange.toLowerCase()] ?? 1;
45
+ export function getFundingHours(ref) {
46
+ const basis = venueFundingBasis(ref);
47
+ if (basis.kind !== "perHours") {
48
+ throw new PerpError("INVALID_PARAMS", `Funding basis of "${ref}" is annualized, not a number of hours`, {
49
+ remediation: "Use the market's fundingRateBasis with toHourlyRateByBasis()",
50
+ });
51
+ }
52
+ return basis.hours;
30
53
  }
31
- /** Convert a raw funding rate to per-hour rate */
32
- export function toHourlyRate(rate, exchange) {
33
- const hours = EXCHANGE_FUNDING_HOURS[exchange.toLowerCase()] ?? 1;
34
- return rate / hours;
54
+ /** Convert a raw quoted rate to a per-hour rate using an explicit (market) basis. */
55
+ export function toHourlyRateByBasis(rate, basis) {
56
+ return rateToHourly(rate, basis);
57
+ }
58
+ /** Convert a raw funding rate to per-hour rate using the venue's basis. */
59
+ export function toHourlyRate(rate, ref) {
60
+ return rateToHourly(rate, venueFundingBasis(ref));
35
61
  }
36
62
  /** Annualize a raw rate from a specific exchange */
37
63
  export function annualizeRate(rate, exchange) {
38
- const hourlyRate = toHourlyRate(rate, exchange);
39
- return hourlyRate * HOURLY_PERIODS * 100; // as percentage
64
+ return annualizeHourlyRate(toHourlyRate(rate, exchange));
65
+ }
66
+ /** Annualize a raw rate quoted on an explicit (market) basis */
67
+ export function annualizeRateByBasis(rate, basis) {
68
+ return annualizeHourlyRate(toHourlyRateByBasis(rate, basis));
40
69
  }
41
70
  /** Annualize an already-normalized hourly rate (no exchange conversion needed) */
42
71
  export function annualizeHourlyRate(hourlyRate) {
@@ -66,13 +95,16 @@ export function computeSignedAnnualSpread(shortRate, shortExchange, longRate, lo
66
95
  /**
67
96
  * Estimate hourly funding payment for a position.
68
97
  * @param rate - raw funding rate from the exchange
69
- * @param exchange - exchange name
98
+ * @param exchange - venue ref
70
99
  * @param positionUsd - position notional in USD
71
100
  * @param side - "long" or "short" (longs pay positive rate, shorts receive)
72
101
  * @returns hourly payment in USD (positive = you pay, negative = you receive)
73
102
  */
74
103
  export function estimateHourlyFunding(rate, exchange, positionUsd, side) {
75
- const hourlyRate = toHourlyRate(rate, exchange);
104
+ return estimateHourlyFundingFromHourly(toHourlyRate(rate, exchange), positionUsd, side);
105
+ }
106
+ /** Same as estimateHourlyFunding, from an already-normalized hourly rate. */
107
+ export function estimateHourlyFundingFromHourly(hourlyRate, positionUsd, side) {
76
108
  // Long pays positive funding, short receives positive funding
77
109
  const multiplier = side === "long" ? 1 : -1;
78
110
  return hourlyRate * positionUsd * multiplier;
@@ -1,22 +1,36 @@
1
1
  /**
2
- * Real-time 3-DEX funding rate comparison.
2
+ * Real-time cross-venue funding rate comparison.
3
3
  *
4
- * Fetches funding rates from Pacifica, Hyperliquid, and Lighter in parallel,
5
- * normalizes them to comparable hourly rates, and identifies arbitrage
6
- * opportunities across exchanges.
4
+ * Fans out over every venue with the "marketData" role (design §10.6) using
5
+ * each venue's `publicData.fetchFundingRates(net)`, normalizes every row to a
6
+ * per-hour rate with the row's own basis (Lighter
7
+ * family 8h, Aster per-symbol), and matches markets across venues by
8
+ * `canonical` (null → excluded, §10.9).
9
+ *
10
+ * A venue that fails is reported in `exchangeStatus` ("error") and
11
+ * `exchangeErrors` (message) — its rows are absent, never silently empty.
7
12
  */
8
13
  import { type HistoricalAverages } from "./history.js";
14
+ import { type VenueDefinition } from "../exchanges/venue.js";
15
+ import { type FundingRateBasis, type Network, type VenueId } from "../exchanges/venue-types.js";
9
16
  export interface ExchangeFundingRate {
10
- exchange: "pacifica" | "hyperliquid" | "lighter" | "aster";
17
+ exchange: VenueId;
18
+ /** Venue display symbol (e.g. "kPEPE", "BTC"). */
11
19
  symbol: string;
20
+ /** Cross-venue matching key (canonical-symbols.ts). */
21
+ canonical: string;
12
22
  fundingRate: number;
23
+ basis: FundingRateBasis;
13
24
  hourlyRate: number;
14
25
  annualizedPct: number;
15
26
  markPrice: number;
16
- nextFundingTime?: number;
17
- historicalAvg?: HistoricalAverages;
27
+ nextFundingTime: number | null;
28
+ historicalAvg: HistoricalAverages | null;
29
+ /** false = the venue's funding rate is unverified (VenueDefinition.fundingVerified) — shown only on explicit request. */
30
+ fundingVerified: boolean;
18
31
  }
19
32
  export interface SymbolFundingComparison {
33
+ /** Canonical symbol shared by every row. */
20
34
  symbol: string;
21
35
  rates: ExchangeFundingRate[];
22
36
  maxSpreadAnnual: number;
@@ -29,20 +43,38 @@ export interface FundingRateSnapshot {
29
43
  timestamp: string;
30
44
  symbols: SymbolFundingComparison[];
31
45
  exchangeStatus: Record<string, "ok" | "error">;
46
+ /** Error message per venue whose status is "error" (§10.13 #3). */
47
+ exchangeErrors: Record<string, string>;
32
48
  }
33
49
  export declare const TOP_SYMBOLS: string[];
34
50
  /**
35
- * Fetch funding rates from all 3 DEXs in parallel, normalize, and compare.
51
+ * Fetch every venue in `venues` concurrently; failures land in status/errors.
52
+ * Venues whose funding is unverified (VenueDefinition.fundingVerified false — QFEX until its
53
+ * rate unit is confirmed) are DROPPED unless `includeUnverified`: every consumer that ranks,
54
+ * alerts on or trades funding spreads (arb scan, MCP, alerts, dashboard, portfolio) leaves it
55
+ * false. Only explicit, labelled reads pass true (`arb scan --include-unverified`).
56
+ */
57
+ export declare function fetchVenuesRates(venues: VenueDefinition[], net: Network, includeUnverified: boolean): Promise<{
58
+ rates: ExchangeFundingRate[];
59
+ exchangeStatus: Record<string, "ok" | "error">;
60
+ exchangeErrors: Record<string, string>;
61
+ }>;
62
+ /**
63
+ * Fetch funding rates from every market-data venue in parallel, normalize, and compare.
36
64
  * Returns rates sorted by max spread (descending).
65
+ * @param opts.network defaults to the network the CLI selected (setSharedApiNetwork)
37
66
  */
38
67
  export declare function fetchAllFundingRates(opts?: {
39
68
  symbols?: string[];
40
69
  minSpread?: number;
70
+ network?: Network;
71
+ /** Also fetch venues whose funding rate is unverified (default false — see fetchVenuesRates). */
72
+ includeUnverified?: boolean;
41
73
  }): Promise<FundingRateSnapshot>;
42
74
  /**
43
- * Fetch rates for a single symbol across all exchanges.
75
+ * Fetch rates for a single (canonical) symbol across all exchanges.
44
76
  */
45
- export declare function fetchSymbolFundingRates(symbol: string): Promise<SymbolFundingComparison | null>;
77
+ export declare function fetchSymbolFundingRates(symbol: string, includeUnverified?: boolean): Promise<SymbolFundingComparison | null>;
46
78
  export interface SpotPerpSpread {
47
79
  symbol: string;
48
80
  /** Perp exchange with the highest absolute funding rate */
@@ -65,7 +97,7 @@ export interface SpotPerpSpread {
65
97
  /**
66
98
  * Fetch spot+perp funding rate spreads.
67
99
  * Since spot has 0 funding cost, the spread is simply |perp funding rate|.
68
- * Only includes symbols available on at least one spot exchange (HL or LT).
100
+ * Only includes symbols available on at least one bot spot venue (def.spot, §12.4 #3).
69
101
  *
70
102
  * Key safety checks:
71
103
  * - U-token mapping: UBTC→BTC, UETH→ETH, USOL→SOL, UFART→FARTCOIN
@@ -75,7 +107,10 @@ export interface SpotPerpSpread {
75
107
  export declare function fetchSpotPerpSpreads(opts?: {
76
108
  symbols?: string[];
77
109
  minSpread?: number;
110
+ network?: Network;
78
111
  }): Promise<{
79
112
  timestamp: string;
80
113
  spreads: SpotPerpSpread[];
114
+ exchangeStatus: Record<string, "ok" | "error">;
115
+ exchangeErrors: Record<string, string>;
81
116
  }>;