perp-cli 0.14.3 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/README.ja.md +243 -0
  2. package/README.ko.md +243 -0
  3. package/README.md +138 -405
  4. package/README.zh.md +243 -0
  5. package/dist/agent-wallet/store.d.ts +3 -2
  6. package/dist/agent-wallet/store.js +2 -2
  7. package/dist/api/public/hyperliquid.js +4 -0
  8. package/dist/api/public/lighter.d.ts +5 -0
  9. package/dist/api/public/lighter.js +5 -0
  10. package/dist/api/public/pacifica.js +85 -15
  11. package/dist/api/public/urls.d.ts +2 -0
  12. package/dist/api/public/urls.js +3 -0
  13. package/dist/arb/sizing.js +4 -2
  14. package/dist/arb/state.d.ts +6 -0
  15. package/dist/arb/utils.d.ts +1 -2
  16. package/dist/arb/utils.js +1 -2
  17. package/dist/balance-by-address.d.ts +39 -0
  18. package/dist/balance-by-address.js +44 -0
  19. package/dist/bot/apex/pulse.js +3 -0
  20. package/dist/bot/apex/radar.js +2 -1
  21. package/dist/bot/engine.d.ts +10 -1
  22. package/dist/bot/engine.js +14 -6
  23. package/dist/bot/indicators.d.ts +7 -0
  24. package/dist/bot/indicators.js +16 -0
  25. package/dist/bot/perp-order.d.ts +4 -4
  26. package/dist/bot/perp-order.js +5 -5
  27. package/dist/bot/quarantine.d.ts +1 -1
  28. package/dist/bot/quarantine.js +1 -1
  29. package/dist/bot/quote-rules.js +1 -1
  30. package/dist/bot/strategies/apex-strategy.js +3 -2
  31. package/dist/bot/strategies/engine-mm.js +6 -5
  32. package/dist/bot/strategies/funding-arb-strategy.js +12 -5
  33. package/dist/bot/strategies/funding-arb-utils.d.ts +15 -3
  34. package/dist/bot/strategies/funding-arb-utils.js +53 -20
  35. package/dist/bot/strategies/funding-auto.js +2 -2
  36. package/dist/bot/strategies/liquidation-mm.d.ts +1 -0
  37. package/dist/bot/strategies/liquidation-mm.js +8 -2
  38. package/dist/bot/strategies/momentum-breakout.d.ts +1 -0
  39. package/dist/bot/strategies/momentum-breakout.js +11 -3
  40. package/dist/bot/strategies/spot-perp-arb-strategy.d.ts +1 -1
  41. package/dist/bot/strategies/spot-perp-arb-strategy.js +6 -4
  42. package/dist/bot/strategies/spot-perp-executor.d.ts +1 -1
  43. package/dist/bot/strategies/spot-perp-executor.js +3 -3
  44. package/dist/bot/strategy-types.d.ts +2 -1
  45. package/dist/bot/tui/BotDashboard.d.ts +1 -1
  46. package/dist/bot/tui/BotDashboard.js +1 -1
  47. package/dist/cache.js +12 -6
  48. package/dist/cli-program.d.ts +15 -0
  49. package/dist/cli-program.js +126 -6
  50. package/dist/commands/account.js +168 -24
  51. package/dist/commands/agent-import.d.ts +7 -0
  52. package/dist/commands/agent-import.js +30 -1
  53. package/dist/commands/agent.d.ts +6 -3
  54. package/dist/commands/agent.js +160 -12
  55. package/dist/commands/arb/index.js +23 -81
  56. package/dist/commands/arb-auto.d.ts +24 -0
  57. package/dist/commands/arb-auto.js +175 -97
  58. package/dist/commands/arb.d.ts +20 -0
  59. package/dist/commands/arb.js +107 -163
  60. package/dist/commands/backtest.js +23 -21
  61. package/dist/commands/bot.js +1 -1
  62. package/dist/commands/builder.js +1 -1
  63. package/dist/commands/funds.js +113 -3
  64. package/dist/commands/init.d.ts +1 -1
  65. package/dist/commands/init.js +27 -7
  66. package/dist/commands/manage.js +23 -21
  67. package/dist/commands/market.d.ts +48 -0
  68. package/dist/commands/market.js +395 -100
  69. package/dist/commands/options.d.ts +14 -0
  70. package/dist/commands/options.js +151 -0
  71. package/dist/commands/pacifica-earn.d.ts +5 -0
  72. package/dist/commands/pacifica-earn.js +455 -0
  73. package/dist/commands/pacifica-orders.d.ts +14 -0
  74. package/dist/commands/pacifica-orders.js +142 -0
  75. package/dist/commands/portfolio.d.ts +16 -0
  76. package/dist/commands/portfolio.js +83 -55
  77. package/dist/commands/rebalance.d.ts +1 -0
  78. package/dist/commands/rebalance.js +15 -0
  79. package/dist/commands/risk.d.ts +11 -2
  80. package/dist/commands/risk.js +39 -44
  81. package/dist/commands/trade.d.ts +1 -0
  82. package/dist/commands/trade.js +67 -62
  83. package/dist/commands/wallet.js +1 -1
  84. package/dist/config.d.ts +2 -2
  85. package/dist/config.js +15 -4
  86. package/dist/constants.js +6 -0
  87. package/dist/cross-chain-margin.d.ts +3 -1
  88. package/dist/cross-chain-margin.js +4 -2
  89. package/dist/dashboard/server.js +3 -3
  90. package/dist/dashboard/ui.js +9 -6
  91. package/dist/errors.d.ts +29 -1
  92. package/dist/errors.js +35 -3
  93. package/dist/exchanges/address.d.ts +8 -0
  94. package/dist/exchanges/address.js +47 -0
  95. package/dist/exchanges/arcus/adapter.d.ts +16 -12
  96. package/dist/exchanges/arcus/adapter.js +45 -18
  97. package/dist/exchanges/arcus/agent.d.ts +1 -1
  98. package/dist/exchanges/arcus/agent.js +1 -1
  99. package/dist/exchanges/arcus/client.js +1 -1
  100. package/dist/exchanges/arcus/public.js +3 -2
  101. package/dist/exchanges/arcus/signing.d.ts +2 -3
  102. package/dist/exchanges/arcus/signing.js +1 -1
  103. package/dist/exchanges/arcus/spot-chain.d.ts +1 -1
  104. package/dist/exchanges/arcus/spot-chain.js +1 -1
  105. package/dist/exchanges/arcus/spot-router.d.ts +1 -1
  106. package/dist/exchanges/arcus/spot-router.js +2 -2
  107. package/dist/exchanges/arcus/spot.d.ts +2 -3
  108. package/dist/exchanges/arcus/spot.js +2 -3
  109. package/dist/exchanges/aster-spot.d.ts +3 -3
  110. package/dist/exchanges/aster-spot.js +6 -9
  111. package/dist/exchanges/aster-typed-data.d.ts +1 -1
  112. package/dist/exchanges/aster-typed-data.js +1 -1
  113. package/dist/exchanges/aster.d.ts +30 -10
  114. package/dist/exchanges/aster.js +153 -53
  115. package/dist/exchanges/builder-fee.d.ts +1 -1
  116. package/dist/exchanges/builder-fee.js +13 -2
  117. package/dist/exchanges/canonical-symbols.d.ts +8 -2
  118. package/dist/exchanges/canonical-symbols.js +46 -2
  119. package/dist/exchanges/capabilities.d.ts +2 -0
  120. package/dist/exchanges/capabilities.js +2 -1
  121. package/dist/exchanges/derive/client.d.ts +37 -0
  122. package/dist/exchanges/derive/client.js +135 -0
  123. package/dist/exchanges/derive/options.d.ts +73 -0
  124. package/dist/exchanges/derive/options.js +379 -0
  125. package/dist/exchanges/extended/adapter.d.ts +96 -0
  126. package/dist/exchanges/extended/adapter.js +241 -0
  127. package/dist/exchanges/extended/client.d.ts +38 -0
  128. package/dist/exchanges/extended/client.js +88 -0
  129. package/dist/exchanges/extended/public.d.ts +133 -0
  130. package/dist/exchanges/extended/public.js +436 -0
  131. package/dist/exchanges/grvt/adapter.d.ts +100 -0
  132. package/dist/exchanges/grvt/adapter.js +283 -0
  133. package/dist/exchanges/grvt/client.d.ts +25 -0
  134. package/dist/exchanges/grvt/client.js +86 -0
  135. package/dist/exchanges/grvt/public.d.ts +151 -0
  136. package/dist/exchanges/grvt/public.js +438 -0
  137. package/dist/exchanges/hyperliquid-outcome.d.ts +2 -0
  138. package/dist/exchanges/hyperliquid-outcome.js +29 -1
  139. package/dist/exchanges/hyperliquid-spot.d.ts +9 -1
  140. package/dist/exchanges/hyperliquid-spot.js +24 -16
  141. package/dist/exchanges/hyperliquid.d.ts +199 -22
  142. package/dist/exchanges/hyperliquid.js +550 -202
  143. package/dist/exchanges/index.d.ts +1 -1
  144. package/dist/exchanges/index.js +1 -1
  145. package/dist/exchanges/interface.d.ts +157 -13
  146. package/dist/exchanges/interface.js +47 -0
  147. package/dist/exchanges/ioc-outcome.d.ts +1 -1
  148. package/dist/exchanges/ioc-outcome.js +1 -1
  149. package/dist/exchanges/legacy-trading-v2.d.ts +2 -2
  150. package/dist/exchanges/legacy-trading-v2.js +7 -2
  151. package/dist/exchanges/lighter-public.d.ts +67 -12
  152. package/dist/exchanges/lighter-public.js +250 -82
  153. package/dist/exchanges/lighter-signer.d.ts +1 -1
  154. package/dist/exchanges/lighter-signer.js +1 -1
  155. package/dist/exchanges/lighter-spot.d.ts +10 -5
  156. package/dist/exchanges/lighter-spot.js +105 -97
  157. package/dist/exchanges/lighter.d.ts +80 -21
  158. package/dist/exchanges/lighter.js +312 -105
  159. package/dist/exchanges/ondo/adapter.d.ts +38 -13
  160. package/dist/exchanges/ondo/adapter.js +86 -27
  161. package/dist/exchanges/ondo/agent.d.ts +1 -1
  162. package/dist/exchanges/ondo/agent.js +1 -1
  163. package/dist/exchanges/ondo/client.d.ts +1 -1
  164. package/dist/exchanges/ondo/client.js +2 -2
  165. package/dist/exchanges/ondo/public.d.ts +35 -3
  166. package/dist/exchanges/ondo/public.js +75 -32
  167. package/dist/exchanges/ondo/spot.d.ts +2 -2
  168. package/dist/exchanges/ondo/spot.js +3 -3
  169. package/dist/exchanges/options-interface.d.ts +158 -0
  170. package/dist/exchanges/options-interface.js +17 -0
  171. package/dist/exchanges/options-venues.d.ts +12 -0
  172. package/dist/exchanges/options-venues.js +35 -0
  173. package/dist/exchanges/outcome-interface.d.ts +4 -0
  174. package/dist/exchanges/pacifica-atomic.d.ts +211 -0
  175. package/dist/exchanges/pacifica-atomic.js +440 -0
  176. package/dist/exchanges/pacifica-decimal.d.ts +10 -0
  177. package/dist/exchanges/pacifica-decimal.js +51 -0
  178. package/dist/exchanges/pacifica-presigned.d.ts +53 -0
  179. package/dist/exchanges/pacifica-presigned.js +141 -0
  180. package/dist/exchanges/pacifica-print.d.ts +200 -0
  181. package/dist/exchanges/pacifica-print.js +417 -0
  182. package/dist/exchanges/pacifica-spot.d.ts +8 -2
  183. package/dist/exchanges/pacifica-spot.js +26 -18
  184. package/dist/exchanges/pacifica-typed-data.d.ts +1 -1
  185. package/dist/exchanges/pacifica-typed-data.js +1 -1
  186. package/dist/exchanges/pacifica-vaults.d.ts +130 -0
  187. package/dist/exchanges/pacifica-vaults.js +277 -0
  188. package/dist/exchanges/pacifica.d.ts +108 -10
  189. package/dist/exchanges/pacifica.js +428 -171
  190. package/dist/exchanges/precision.d.ts +3 -1
  191. package/dist/exchanges/precision.js +9 -2
  192. package/dist/exchanges/public-balances.d.ts +25 -0
  193. package/dist/exchanges/public-balances.js +158 -0
  194. package/dist/exchanges/public-positions.d.ts +43 -0
  195. package/dist/exchanges/public-positions.js +154 -0
  196. package/dist/exchanges/qfex/adapter.d.ts +69 -13
  197. package/dist/exchanges/qfex/adapter.js +102 -17
  198. package/dist/exchanges/qfex/agent.d.ts +1 -1
  199. package/dist/exchanges/qfex/agent.js +1 -1
  200. package/dist/exchanges/qfex/client.d.ts +1 -1
  201. package/dist/exchanges/qfex/client.js +1 -1
  202. package/dist/exchanges/qfex/errors.d.ts +1 -1
  203. package/dist/exchanges/qfex/errors.js +2 -2
  204. package/dist/exchanges/qfex/public.d.ts +65 -12
  205. package/dist/exchanges/qfex/public.js +131 -25
  206. package/dist/exchanges/qfex/signing.d.ts +2 -2
  207. package/dist/exchanges/qfex/signing.js +4 -5
  208. package/dist/exchanges/qfex/ws-transport.d.ts +3 -3
  209. package/dist/exchanges/qfex/ws-transport.js +3 -3
  210. package/dist/exchanges/rate-limiter.d.ts +1 -1
  211. package/dist/exchanges/rate-limiter.js +5 -2
  212. package/dist/exchanges/registry.d.ts +1 -1
  213. package/dist/exchanges/registry.js +1 -1
  214. package/dist/exchanges/risex/adapter.d.ts +160 -0
  215. package/dist/exchanges/risex/adapter.js +842 -0
  216. package/dist/exchanges/risex/agent.d.ts +154 -0
  217. package/dist/exchanges/risex/agent.js +384 -0
  218. package/dist/exchanges/risex/client.d.ts +47 -0
  219. package/dist/exchanges/risex/client.js +174 -0
  220. package/dist/exchanges/risex/nonce.d.ts +43 -0
  221. package/dist/exchanges/risex/nonce.js +212 -0
  222. package/dist/exchanges/risex/public.d.ts +64 -0
  223. package/dist/exchanges/risex/public.js +150 -0
  224. package/dist/exchanges/risex/session.d.ts +71 -0
  225. package/dist/exchanges/risex/session.js +171 -0
  226. package/dist/exchanges/risex/typed-data.d.ts +173 -0
  227. package/dist/exchanges/risex/typed-data.js +240 -0
  228. package/dist/exchanges/risex/units.d.ts +29 -0
  229. package/dist/exchanges/risex/units.js +104 -0
  230. package/dist/exchanges/slippage.d.ts +1 -1
  231. package/dist/exchanges/slippage.js +1 -1
  232. package/dist/exchanges/spot-factory.d.ts +3 -3
  233. package/dist/exchanges/spot-factory.js +8 -8
  234. package/dist/exchanges/spot-interface.d.ts +5 -5
  235. package/dist/exchanges/spot-interface.js +2 -2
  236. package/dist/exchanges/spot-result.d.ts +3 -3
  237. package/dist/exchanges/spot-result.js +3 -3
  238. package/dist/exchanges/trading-v2.d.ts +3 -3
  239. package/dist/exchanges/trading-v2.js +9 -6
  240. package/dist/exchanges/txflow/adapter.d.ts +61 -0
  241. package/dist/exchanges/txflow/adapter.js +150 -0
  242. package/dist/exchanges/txflow/client.d.ts +47 -0
  243. package/dist/exchanges/txflow/client.js +155 -0
  244. package/dist/exchanges/txflow/public.d.ts +87 -0
  245. package/dist/exchanges/txflow/public.js +355 -0
  246. package/dist/exchanges/unknown-symbol.d.ts +34 -0
  247. package/dist/exchanges/unknown-symbol.js +56 -0
  248. package/dist/exchanges/variational/adapter.d.ts +67 -0
  249. package/dist/exchanges/variational/adapter.js +137 -0
  250. package/dist/exchanges/variational/client.d.ts +21 -0
  251. package/dist/exchanges/variational/client.js +66 -0
  252. package/dist/exchanges/variational/public.d.ts +126 -0
  253. package/dist/exchanges/variational/public.js +430 -0
  254. package/dist/exchanges/venue-types.d.ts +52 -10
  255. package/dist/exchanges/venue-types.js +82 -11
  256. package/dist/exchanges/venue.d.ts +150 -11
  257. package/dist/exchanges/venue.js +126 -4
  258. package/dist/exchanges/venues/arcus.d.ts +1 -2
  259. package/dist/exchanges/venues/arcus.js +5 -4
  260. package/dist/exchanges/venues/aster.d.ts +2 -2
  261. package/dist/exchanges/venues/aster.js +6 -4
  262. package/dist/exchanges/venues/create-helpers.d.ts +1 -1
  263. package/dist/exchanges/venues/create-helpers.js +3 -3
  264. package/dist/exchanges/venues/extended.d.ts +21 -0
  265. package/dist/exchanges/venues/extended.js +96 -0
  266. package/dist/exchanges/venues/grvt.d.ts +30 -0
  267. package/dist/exchanges/venues/grvt.js +98 -0
  268. package/dist/exchanges/venues/hyperliquid.d.ts +2 -2
  269. package/dist/exchanges/venues/hyperliquid.js +19 -8
  270. package/dist/exchanges/venues/index.d.ts +7 -2
  271. package/dist/exchanges/venues/index.js +8 -2
  272. package/dist/exchanges/venues/lighter-family.d.ts +7 -9
  273. package/dist/exchanges/venues/lighter-family.js +9 -11
  274. package/dist/exchanges/venues/lighter-rh.d.ts +2 -2
  275. package/dist/exchanges/venues/lighter-rh.js +20 -8
  276. package/dist/exchanges/venues/lighter.d.ts +1 -1
  277. package/dist/exchanges/venues/lighter.js +18 -6
  278. package/dist/exchanges/venues/ondo.d.ts +1 -1
  279. package/dist/exchanges/venues/ondo.js +5 -3
  280. package/dist/exchanges/venues/pacifica.d.ts +2 -2
  281. package/dist/exchanges/venues/pacifica.js +15 -4
  282. package/dist/exchanges/venues/qfex.d.ts +1 -1
  283. package/dist/exchanges/venues/qfex.js +4 -2
  284. package/dist/exchanges/venues/risex-release.d.ts +14 -0
  285. package/dist/exchanges/venues/risex-release.js +14 -0
  286. package/dist/exchanges/venues/risex.d.ts +31 -0
  287. package/dist/exchanges/venues/risex.js +131 -0
  288. package/dist/exchanges/venues/txflow.d.ts +18 -0
  289. package/dist/exchanges/venues/txflow.js +77 -0
  290. package/dist/exchanges/venues/variational.d.ts +21 -0
  291. package/dist/exchanges/venues/variational.js +85 -0
  292. package/dist/execution-log.d.ts +1 -1
  293. package/dist/funding/legacy-public.d.ts +6 -4
  294. package/dist/funding/legacy-public.js +42 -41
  295. package/dist/funding/normalize.d.ts +1 -1
  296. package/dist/funding/normalize.js +1 -1
  297. package/dist/funding/rates.d.ts +95 -6
  298. package/dist/funding/rates.js +99 -19
  299. package/dist/index.js +7 -6
  300. package/dist/jobs.d.ts +1 -0
  301. package/dist/jobs.js +25 -1
  302. package/dist/landing.d.ts +2 -0
  303. package/dist/landing.js +1 -1
  304. package/dist/liquidity.d.ts +3 -1
  305. package/dist/liquidity.js +8 -4
  306. package/dist/mcp-pacifica-earn.d.ts +9 -0
  307. package/dist/mcp-pacifica-earn.js +64 -0
  308. package/dist/mcp-server.js +211 -68
  309. package/dist/pacifica/client.d.ts +69 -5
  310. package/dist/pacifica/client.js +181 -8
  311. package/dist/pacifica/rate-limit.d.ts +144 -0
  312. package/dist/pacifica/rate-limit.js +267 -0
  313. package/dist/pacifica/types/order.d.ts +2 -1
  314. package/dist/plan-executor.js +7 -2
  315. package/dist/positions-by-address.d.ts +34 -0
  316. package/dist/positions-by-address.js +46 -0
  317. package/dist/rebalance.js +1 -1
  318. package/dist/risk.d.ts +2 -1
  319. package/dist/risk.js +2 -4
  320. package/dist/settings.d.ts +32 -3
  321. package/dist/signer/ows-evm.d.ts +1 -1
  322. package/dist/signer/ows-evm.js +1 -1
  323. package/dist/smart-order.d.ts +1 -1
  324. package/dist/smart-order.js +1 -1
  325. package/dist/strategies/funding-arb.d.ts +1 -1
  326. package/dist/strategies/funding-arb.js +36 -63
  327. package/dist/trade-validator.js +2 -2
  328. package/dist/utils.d.ts +22 -3
  329. package/dist/utils.js +11 -3
  330. package/dist/venue-health.d.ts +40 -0
  331. package/dist/venue-health.js +75 -0
  332. package/dist/withdraw-gate.d.ts +1 -1
  333. package/dist/withdraw-gate.js +1 -1
  334. package/dist/ws/arcus-market.d.ts +9 -0
  335. package/dist/ws/arcus-market.js +9 -0
  336. package/dist/ws/aster-market.d.ts +33 -0
  337. package/dist/ws/aster-market.js +30 -0
  338. package/dist/ws/index.d.ts +980 -0
  339. package/dist/ws/index.js +4460 -0
  340. package/dist/ws/lighter-market.d.ts +14 -0
  341. package/dist/ws/lighter-market.js +13 -0
  342. package/dist/ws/node.d.ts +996 -0
  343. package/dist/ws/node.js +4554 -0
  344. package/dist/ws/pacifica-instrument.d.ts +8 -0
  345. package/dist/ws/pacifica-instrument.js +8 -0
  346. package/dist/ws/unclassified.d.ts +16 -0
  347. package/dist/ws/unclassified.js +43 -0
  348. package/dist/ws-cli/credentials.d.ts +62 -0
  349. package/dist/ws-cli/credentials.js +126 -0
  350. package/package.json +71 -10
  351. package/skills/perp-cli/SKILL.md +153 -36
  352. package/skills/perp-cli/package.json +15 -2
  353. package/skills/perp-cli/references/agent-operations.md +22 -12
  354. package/skills/perp-cli/references/commands.md +143 -17
  355. package/skills/perp-cli/references/strategies.md +38 -3
  356. package/skills/perp-cli/references/ws-library.md +523 -0
  357. package/skills/perp-cli/scripts/arb-monitor.sh +13 -10
  358. package/skills/perp-cli/scripts/funding-analysis.sh +57 -29
  359. package/skills/perp-cli/scripts/preflight.sh +27 -19
  360. package/skills/perp-cli/scripts/spot-perp-scan.sh +58 -38
  361. package/skills/perp-cli/scripts/validate-arb.sh +56 -39
  362. package/dist/cli-spec.d.ts +0 -46
  363. package/dist/cli-spec.js +0 -81
@@ -0,0 +1,130 @@
1
+ import type { PacificaClient } from "../pacifica/client.js";
2
+ import { type PresignedIdentity, type PresignedRequest } from "./pacifica-presigned.js";
3
+ /** docs vaults/depositing: "Minimum deposit — Constant 10 USDC." */
4
+ export declare const VAULT_MIN_DEPOSIT_USDC = "10";
5
+ export interface VaultConfig {
6
+ depositCap: string | null;
7
+ managerProfitShare: string | null;
8
+ managerLossShare: string | null;
9
+ depositMinDurationMs: number | null;
10
+ managerMinBalancePortion: string | null;
11
+ managerLiquidationBalancePortion: string | null;
12
+ withdrawWindowS: number | null;
13
+ withdrawDurationS: number | null;
14
+ }
15
+ export interface PacificaVault {
16
+ schema: 1;
17
+ address: string;
18
+ nickname: string | null;
19
+ creator: string | null;
20
+ manager: string | null;
21
+ referrer: string | null;
22
+ createdAt: number | null;
23
+ lpShares: string;
24
+ managerShares: string;
25
+ lpBalance: string;
26
+ managerBalance: string;
27
+ /** lp_balance + manager_balance (USDC attributed to the two share classes). */
28
+ tvl: string;
29
+ /** last_checked_equity — the equity snapshot used for vault accounting. */
30
+ equitySnapshot: string | null;
31
+ highWatermark: string | null;
32
+ /** lp_balance ÷ lp_shares (null when the LP class is empty — the next deposit mints 1:1). */
33
+ navPerLpShare: string | null;
34
+ navPerManagerShare: string | null;
35
+ /** Not published by the venue. */
36
+ apy: null;
37
+ config: VaultConfig;
38
+ /** The queried account's LP shares (`user_share`); null when none / not queried. */
39
+ userShares: string | null;
40
+ }
41
+ export declare function parseVault(x: unknown): PacificaVault;
42
+ /** GET /lake/list `data` (`{lakes: [...]}`). */
43
+ export declare function parseVaultList(data: unknown): PacificaVault[];
44
+ type Reader = Pick<PacificaClient, "getEnvelope">;
45
+ export declare function fetchVaults(client: Reader, account: string | null): Promise<PacificaVault[]>;
46
+ /**
47
+ * Vault by address, or by a nickname (case-insensitive) that matches EXACTLY ONE vault. Nicknames
48
+ * are not unique in practice (live 2026-10-19: "Pacifica Vault" / "Pacifica vault", "Shark vault" /
49
+ * "shark vault"), so two or more matches are INVALID_PARAMS listing every candidate — never the
50
+ * first / newest one (a copycat vault must not receive a deposit).
51
+ */
52
+ export declare function findVault(vaults: PacificaVault[], ref: string): PacificaVault;
53
+ /** UNOFFICIAL endpoint (not in the API docs; used by app.pacifica.fi). Advisory only — the venue's own refusal is final. */
54
+ export declare const DEPOSIT_WHITELIST_API_STATUS: "unofficial";
55
+ export declare function fetchDepositWhitelist(client: Reader, vault: string): Promise<string[]>;
56
+ /**
57
+ * The advisory whitelist read for display: `addresses` null = unreadable, with the error CODE that
58
+ * made it so (never a bare null that looks like "no whitelist data"). The venue's refusal of a
59
+ * deposit stays final either way.
60
+ */
61
+ export declare function readDepositWhitelist(client: Reader, vault: string): Promise<{
62
+ addresses: string[] | null;
63
+ error: string | null;
64
+ }>;
65
+ export interface WithdrawWindow {
66
+ /** No window configured: always open (subject to the other rules). */
67
+ restricted: boolean;
68
+ open: boolean;
69
+ /** Current window closes (open) or next one opens (closed), ms; null when unrestricted. */
70
+ nextChangeAt: number | null;
71
+ }
72
+ /** docs: open while current_unix_time_s mod withdraw_window_s < withdraw_duration_s (epoch-anchored). */
73
+ export declare function withdrawWindowAt(c: VaultConfig, nowMs: number): WithdrawWindow;
74
+ /** Shares this account holds in the vault: manager shares for the manager, else LP `user_share`. */
75
+ export declare function heldShares(v: PacificaVault, account: string): {
76
+ role: "manager" | "lp";
77
+ shares: string | null;
78
+ nav: string | null;
79
+ };
80
+ export interface VaultDepositPlan {
81
+ schema: 1;
82
+ vault: string;
83
+ nickname: string | null;
84
+ manager: string | null;
85
+ role: "manager" | "lp";
86
+ amount: string;
87
+ /** amount × shares ÷ balance of the class now (the venue mints at the post-sync NAV). */
88
+ estimatedShares: string | null;
89
+ lockMs: number | null;
90
+ warnings: string[];
91
+ }
92
+ /**
93
+ * Validate a deposit (docs vaults/depositing: min 10 USDC, deposit cap on the LP balance,
94
+ * available_to_withdraw, deposit whitelist). Throws INVALID_PARAMS / INSUFFICIENT_BALANCE / POLICY_DENIED.
95
+ */
96
+ export declare function planVaultDeposit(v: PacificaVault, account: string, amountRaw: string, ctx: {
97
+ availableToWithdraw: string;
98
+ whitelist: string[] | null;
99
+ }): VaultDepositPlan;
100
+ export interface VaultWithdrawPlan {
101
+ schema: 1;
102
+ vault: string;
103
+ nickname: string | null;
104
+ manager: string | null;
105
+ role: "manager" | "lp";
106
+ shares: string;
107
+ heldShares: string;
108
+ /** shares × NAV now (the venue pays at the post-sync NAV; may pay partially when the vault is deployed). */
109
+ estimatedAmount: string | null;
110
+ /** Always the account itself — the API has no destination. */
111
+ destination: string;
112
+ window: WithdrawWindow;
113
+ warnings: string[];
114
+ }
115
+ /** Validate a withdrawal: shares held, withdrawal window. Throws POSITION_NOT_FOUND / INVALID_PARAMS / POLICY_DENIED. */
116
+ export declare function planVaultWithdraw(v: PacificaVault, account: string, sharesRaw: string | "all", ctx: {
117
+ nowMs: number;
118
+ vaultAvailableToWithdraw: string | null;
119
+ }): VaultWithdrawPlan;
120
+ export declare function buildVaultDepositRequest(vault: string, amount: string, identity: PresignedIdentity, opts: {
121
+ timestamp: number;
122
+ idempotencyKey: string;
123
+ expiryWindow?: number;
124
+ }): PresignedRequest;
125
+ export declare function buildVaultWithdrawRequest(vault: string, shares: string, identity: PresignedIdentity, opts: {
126
+ timestamp: number;
127
+ idempotencyKey: string;
128
+ expiryWindow?: number;
129
+ }): PresignedRequest;
130
+ export {};
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Pacifica vaults ("lakes" in the API) — docs.pacifica.fi/vaults.md and pages under it,
3
+ * api-documentation/api/rest-api/vaults/*.
4
+ *
5
+ * Product: a vault is a real Pacifica account traded by its manager; depositors (LPs) get LP
6
+ * shares at NAV (lp_balance ÷ lp_shares, 1:1 when the LP class is empty). PnL is attributed to the
7
+ * LP / manager classes before every deposit or withdrawal; the manager takes `manager_profit_share`
8
+ * of profit above the high-water mark. Minimum deposit 10 USDC; `deposit_cap` caps the LP balance
9
+ * (manager deposits are not counted). A withdrawal redeems shares (amount = shares × NAV) straight
10
+ * into the depositor's own trading balance — the API has no destination field — and is allowed
11
+ * only when: enough shares; `deposit_min_duration_ms` elapsed since the depositor's LAST deposit
12
+ * (each deposit resets the lock for the whole balance); inside the withdrawal window when
13
+ * `withdraw_window_s` / `withdraw_duration_s` are set (open while now_s mod window < duration,
14
+ * epoch-anchored); and the vault has free balance (a fully deployed vault may pay partially).
15
+ * The venue publishes no APY: `apy` is null.
16
+ *
17
+ * Endpoints (GET unauthenticated; writes signed):
18
+ * GET /lake/list[?account=] vaults (+ the account's `user_share`)
19
+ * GET /lake/get_deposit_whitelist?lake= deposit-address whitelist (app.pacifica.fi; not in the API docs)
20
+ * GET /account?account=<vault> · /positions the vault account's live equity / positions
21
+ * POST /lake/deposit type deposit_to_lake {lake, amount, idempotency_key?}
22
+ * POST /lake/withdraw type withdraw_from_lake {lake, shares, idempotency_key?}
23
+ * Live 2026-10-19: absent config fields are omitted (→ null here), and `user_share` was null for a
24
+ * vault's own manager (it counts LP shares; the manager's are `manager_shares`).
25
+ */
26
+ import { PerpError, classifyError } from "../errors.js";
27
+ import { mulDecimal, subDecimal } from "./precision.js";
28
+ import { cmpDecimal, divDecimal, isPlainDecimal, trimDecimal } from "./pacifica-decimal.js";
29
+ import { envelopeData, requireUsdcAmount, PLAIN_POSITIVE } from "./pacifica-print.js";
30
+ import { buildPresigned } from "./pacifica-presigned.js";
31
+ /** docs vaults/depositing: "Minimum deposit — Constant 10 USDC." */
32
+ export const VAULT_MIN_DEPOSIT_USDC = "10";
33
+ function bad(what, row) {
34
+ return new PerpError("EXCHANGE_ERROR", `Pacifica ${what}: ${JSON.stringify(row).slice(0, 200)}`, { exchange: "pacifica" });
35
+ }
36
+ function str(r, k) {
37
+ const v = r[k];
38
+ return typeof v === "string" && v !== "" ? v : null;
39
+ }
40
+ function dec(r, k) {
41
+ const v = r[k];
42
+ return isPlainDecimal(v) ? trimDecimal(v) : null;
43
+ }
44
+ function reqDec(r, k) {
45
+ const v = dec(r, k);
46
+ if (v === null)
47
+ throw bad(`/lake/list row without a decimal ${k}`, r);
48
+ return v;
49
+ }
50
+ function int(r, k) {
51
+ const v = r[k];
52
+ return typeof v === "number" && Number.isInteger(v) ? v : null;
53
+ }
54
+ function add(a, b) {
55
+ return subDecimal(a, `-${b}`.replace(/^--/, ""));
56
+ }
57
+ function parseConfig(x) {
58
+ const c = x !== null && typeof x === "object" && !Array.isArray(x) ? x : {};
59
+ return {
60
+ depositCap: dec(c, "deposit_cap"),
61
+ managerProfitShare: dec(c, "manager_profit_share"),
62
+ managerLossShare: dec(c, "manager_loss_share"),
63
+ depositMinDurationMs: int(c, "deposit_min_duration_ms"),
64
+ managerMinBalancePortion: dec(c, "manager_min_balance_portion"),
65
+ managerLiquidationBalancePortion: dec(c, "manager_liquidation_balance_portion"),
66
+ withdrawWindowS: int(c, "withdraw_window_s"),
67
+ withdrawDurationS: int(c, "withdraw_duration_s"),
68
+ };
69
+ }
70
+ export function parseVault(x) {
71
+ if (x === null || typeof x !== "object" || Array.isArray(x))
72
+ throw bad("/lake/list row is not an object", x);
73
+ const r = x;
74
+ const address = str(r, "address");
75
+ if (address === null)
76
+ throw bad("/lake/list row without an address", r);
77
+ const lpShares = reqDec(r, "lp_shares");
78
+ const managerShares = reqDec(r, "manager_shares");
79
+ const lpBalance = reqDec(r, "lp_balance");
80
+ const managerBalance = reqDec(r, "manager_balance");
81
+ const created = r.created_at;
82
+ return {
83
+ schema: 1,
84
+ address,
85
+ nickname: str(r, "nickname"),
86
+ creator: str(r, "creator"),
87
+ manager: str(r, "manager"),
88
+ referrer: str(r, "referrer"),
89
+ createdAt: typeof created === "number" && created > 0 ? created : null,
90
+ lpShares, managerShares, lpBalance, managerBalance,
91
+ tvl: add(lpBalance, managerBalance),
92
+ equitySnapshot: dec(r, "last_checked_equity"),
93
+ highWatermark: dec(r, "high_watermark"),
94
+ navPerLpShare: divDecimal(lpBalance, lpShares, 12),
95
+ navPerManagerShare: divDecimal(managerBalance, managerShares, 12),
96
+ apy: null,
97
+ config: parseConfig(r.config),
98
+ userShares: dec(r, "user_share"),
99
+ };
100
+ }
101
+ /** GET /lake/list `data` (`{lakes: [...]}`). */
102
+ export function parseVaultList(data) {
103
+ const rows = data !== null && typeof data === "object" && !Array.isArray(data) ? data.lakes : undefined;
104
+ if (!Array.isArray(rows))
105
+ throw bad("/lake/list without a lakes list", data);
106
+ return rows.map(parseVault);
107
+ }
108
+ export async function fetchVaults(client, account) {
109
+ const env = await client.getEnvelope("/lake/list", account !== null ? { account } : {});
110
+ return parseVaultList(envelopeData(env, "/lake/list"));
111
+ }
112
+ /**
113
+ * Vault by address, or by a nickname (case-insensitive) that matches EXACTLY ONE vault. Nicknames
114
+ * are not unique in practice (live 2026-10-19: "Pacifica Vault" / "Pacifica vault", "Shark vault" /
115
+ * "shark vault"), so two or more matches are INVALID_PARAMS listing every candidate — never the
116
+ * first / newest one (a copycat vault must not receive a deposit).
117
+ */
118
+ export function findVault(vaults, ref) {
119
+ const r = ref.trim();
120
+ const byAddress = vaults.find((x) => x.address === r);
121
+ if (byAddress !== undefined)
122
+ return byAddress;
123
+ const matches = vaults.filter((x) => x.nickname !== null && x.nickname.toLowerCase() === r.toLowerCase());
124
+ if (matches.length === 1)
125
+ return matches[0];
126
+ if (matches.length === 0) {
127
+ throw new PerpError("SYMBOL_NOT_FOUND", `No Pacifica vault "${ref}" (address or nickname)`, {
128
+ exchange: "pacifica", remediation: "List them: perp -e pacifica vault list",
129
+ });
130
+ }
131
+ const candidates = matches.map((x) => ({ address: x.address, nickname: x.nickname, manager: x.manager, tvl: x.tvl }));
132
+ throw new PerpError("INVALID_PARAMS", `Vault nickname "${ref}" is ambiguous — ${matches.length} vaults match: ${candidates.map((c) => `${c.address} (${c.nickname}, manager ${c.manager ?? "none"}, TVL ${c.tvl})`).join("; ")}`, {
133
+ exchange: "pacifica", candidates, remediation: "Pass the vault ADDRESS (check its manager first: perp -e pacifica vault info <address>)",
134
+ });
135
+ }
136
+ /** UNOFFICIAL endpoint (not in the API docs; used by app.pacifica.fi). Advisory only — the venue's own refusal is final. */
137
+ export const DEPOSIT_WHITELIST_API_STATUS = "unofficial";
138
+ export async function fetchDepositWhitelist(client, vault) {
139
+ const data = envelopeData(await client.getEnvelope("/lake/get_deposit_whitelist", { lake: vault }), "/lake/get_deposit_whitelist");
140
+ const a = data !== null && typeof data === "object" ? data.addresses : undefined;
141
+ if (!Array.isArray(a) || !a.every((s) => typeof s === "string"))
142
+ throw bad("/lake/get_deposit_whitelist without an addresses list", data);
143
+ return a;
144
+ }
145
+ /**
146
+ * The advisory whitelist read for display: `addresses` null = unreadable, with the error CODE that
147
+ * made it so (never a bare null that looks like "no whitelist data"). The venue's refusal of a
148
+ * deposit stays final either way.
149
+ */
150
+ export async function readDepositWhitelist(client, vault) {
151
+ try {
152
+ return { addresses: await fetchDepositWhitelist(client, vault), error: null };
153
+ }
154
+ catch (e) {
155
+ return { addresses: null, error: classifyError(e, "pacifica").code };
156
+ }
157
+ }
158
+ /** docs: open while current_unix_time_s mod withdraw_window_s < withdraw_duration_s (epoch-anchored). */
159
+ export function withdrawWindowAt(c, nowMs) {
160
+ if (c.withdrawWindowS === null || c.withdrawDurationS === null || c.withdrawWindowS <= 0)
161
+ return { restricted: false, open: true, nextChangeAt: null };
162
+ const now = Math.floor(nowMs / 1000);
163
+ const start = now - (now % c.withdrawWindowS);
164
+ const open = now % c.withdrawWindowS < c.withdrawDurationS;
165
+ return { restricted: true, open, nextChangeAt: (open ? start + c.withdrawDurationS : start + c.withdrawWindowS) * 1000 };
166
+ }
167
+ /** Shares this account holds in the vault: manager shares for the manager, else LP `user_share`. */
168
+ export function heldShares(v, account) {
169
+ if (v.manager === account)
170
+ return { role: "manager", shares: v.managerShares, nav: v.navPerManagerShare };
171
+ return { role: "lp", shares: v.userShares, nav: v.navPerLpShare };
172
+ }
173
+ /**
174
+ * Validate a deposit (docs vaults/depositing: min 10 USDC, deposit cap on the LP balance,
175
+ * available_to_withdraw, deposit whitelist). Throws INVALID_PARAMS / INSUFFICIENT_BALANCE / POLICY_DENIED.
176
+ */
177
+ export function planVaultDeposit(v, account, amountRaw, ctx) {
178
+ const amount = requireUsdcAmount(amountRaw, "vault deposit");
179
+ const where = `vault ${v.nickname ?? v.address}`;
180
+ if (cmpDecimal(amount, VAULT_MIN_DEPOSIT_USDC) < 0) {
181
+ throw new PerpError("INVALID_PARAMS", `${where}: deposit ${amount} USDC is below the ${VAULT_MIN_DEPOSIT_USDC} USDC minimum`, { exchange: "pacifica", remediation: `Deposit at least ${VAULT_MIN_DEPOSIT_USDC} USDC` });
182
+ }
183
+ const { role } = heldShares(v, account);
184
+ // NAV of the class receiving the deposit must be defined and positive (docs: shares = amount ×
185
+ // shares ÷ balance; 1:1 only when the class is EMPTY). Live: XAU_Stable_Growth had lp_shares 10,
186
+ // lp_balance 0 — a deposit there would be priced at NAV 0.
187
+ const [clsShares, clsBalance] = role === "lp" ? [v.lpShares, v.lpBalance] : [v.managerShares, v.managerBalance];
188
+ const sharesZero = cmpDecimal(clsShares, "0") === 0;
189
+ if (sharesZero ? cmpDecimal(clsBalance, "0") !== 0 : cmpDecimal(clsBalance, "0") <= 0) {
190
+ throw new PerpError("INVALID_PARAMS", `${where}: ${role} NAV is ${sharesZero ? "undefined" : "zero"} (${role} shares ${clsShares}, balance ${clsBalance}) — a deposit cannot be priced`, {
191
+ exchange: "pacifica", remediation: "Pick another vault (perp -e pacifica vault list)",
192
+ });
193
+ }
194
+ if (role === "lp" && v.config.depositCap !== null && cmpDecimal(add(v.lpBalance, amount), v.config.depositCap) > 0) {
195
+ throw new PerpError("INVALID_PARAMS", `${where}: LP balance ${v.lpBalance} + ${amount} exceeds the deposit cap ${v.config.depositCap} USDC`, {
196
+ exchange: "pacifica", remediation: `Deposit at most ${subDecimal(v.config.depositCap, v.lpBalance)} USDC`,
197
+ });
198
+ }
199
+ if (cmpDecimal(ctx.availableToWithdraw, amount) < 0) {
200
+ throw new PerpError("INSUFFICIENT_BALANCE", `${where}: deposit ${amount} USDC exceeds available_to_withdraw ${ctx.availableToWithdraw}`, { exchange: "pacifica", remediation: "Deposit less, or free margin first (perp -e pacifica portfolio)" });
201
+ }
202
+ const warnings = [
203
+ "A vault is a third-party trading pool: you can lose up to the whole deposit (Pacifica does not vet or insure managers).",
204
+ `Manager: ${v.manager ?? "none"} — verify this address is the manager you intend to fund.`,
205
+ ];
206
+ // Unofficial whitelist endpoint: advisory only; the venue's refusal is final.
207
+ if (ctx.whitelist === null)
208
+ warnings.push("Deposit whitelist unknown (unofficial endpoint unreadable); the venue refuses if the vault restricts depositors.");
209
+ else if (ctx.whitelist.length > 0 && !ctx.whitelist.includes(account))
210
+ warnings.push(`The vault's deposit whitelist (unofficial endpoint) lists ${ctx.whitelist.length} address(es), not ${account}: the venue will likely refuse.`);
211
+ const lock = v.config.depositMinDurationMs;
212
+ if (lock !== null && lock > 0)
213
+ warnings.push(`Lock-up: no withdrawal for ${(lock / 3_600_000).toFixed(2)} h after this deposit — and the timer restarts for your WHOLE balance in this vault.`);
214
+ if (v.config.withdrawWindowS !== null && v.config.withdrawDurationS !== null) {
215
+ warnings.push(`Withdrawals open only ${v.config.withdrawDurationS} s out of every ${v.config.withdrawWindowS} s (epoch-anchored window).`);
216
+ }
217
+ if (v.manager === null)
218
+ warnings.push("The vault has no manager yet (fresh vault): nobody trades it until a manager claims the seat.");
219
+ if (v.config.managerProfitShare !== null)
220
+ warnings.push(`Manager performance fee: ${v.config.managerProfitShare} of profit above the high-water mark.`);
221
+ return {
222
+ schema: 1, vault: v.address, nickname: v.nickname, manager: v.manager, role, amount,
223
+ // docs: shares_minted = amount × shares ÷ balance of the class (1:1 when the class is empty)
224
+ estimatedShares: role === "lp"
225
+ ? (cmpDecimal(v.lpShares, "0") === 0 ? amount : divDecimal(mulDecimal(amount, v.lpShares), v.lpBalance, 6))
226
+ : (cmpDecimal(v.managerShares, "0") === 0 ? amount : divDecimal(mulDecimal(amount, v.managerShares), v.managerBalance, 6)),
227
+ lockMs: lock, warnings,
228
+ };
229
+ }
230
+ /** Validate a withdrawal: shares held, withdrawal window. Throws POSITION_NOT_FOUND / INVALID_PARAMS / POLICY_DENIED. */
231
+ export function planVaultWithdraw(v, account, sharesRaw, ctx) {
232
+ const where = `vault ${v.nickname ?? v.address}`;
233
+ const held = heldShares(v, account);
234
+ if (held.shares === null || cmpDecimal(held.shares, "0") <= 0) {
235
+ throw new PerpError("POSITION_NOT_FOUND", `${account} holds no ${held.role} shares in ${where}`, { exchange: "pacifica", remediation: "See your vault positions: perp -e pacifica vault positions" });
236
+ }
237
+ let shares;
238
+ if (sharesRaw === "all")
239
+ shares = held.shares;
240
+ else {
241
+ const s = String(sharesRaw).trim();
242
+ if (!PLAIN_POSITIVE.test(s) || !(Number(s) > 0))
243
+ throw new PerpError("INVALID_PARAMS", `shares must be a positive decimal number without leading zeros (got "${sharesRaw}")`, { exchange: "pacifica", remediation: "Pass the shares to redeem, or --all" });
244
+ shares = trimDecimal(s);
245
+ }
246
+ if (cmpDecimal(shares, held.shares) > 0) {
247
+ throw new PerpError("SIZE_TOO_LARGE", `${where}: redeeming ${shares} shares exceeds the ${held.shares} held`, { exchange: "pacifica", remediation: `Redeem at most ${held.shares} (or --all)` });
248
+ }
249
+ const window = withdrawWindowAt(v.config, ctx.nowMs);
250
+ if (!window.open) {
251
+ throw new PerpError("POLICY_DENIED", `${where}: the withdrawal window is closed; it next opens at ${new Date(window.nextChangeAt).toISOString()}`, {
252
+ exchange: "pacifica", remediation: "Withdraw while the window is open (perp -e pacifica vault info <vault> shows it)",
253
+ });
254
+ }
255
+ const estimatedAmount = held.nav === null ? null : trimDecimal(mulDecimal(shares, held.nav));
256
+ const warnings = [];
257
+ const lock = v.config.depositMinDurationMs;
258
+ if (lock !== null && lock > 0)
259
+ warnings.push(`The venue refuses a withdrawal within ${(lock / 3_600_000).toFixed(2)} h of your most recent deposit into this vault (not checkable here).`);
260
+ if (estimatedAmount !== null && ctx.vaultAvailableToWithdraw !== null && cmpDecimal(estimatedAmount, ctx.vaultAvailableToWithdraw) > 0) {
261
+ warnings.push(`The vault's free balance ${ctx.vaultAvailableToWithdraw} USDC is below the ≈${estimatedAmount} USDC redeemed: the venue may pay only part.`);
262
+ }
263
+ return { schema: 1, vault: v.address, nickname: v.nickname, manager: v.manager, role: held.role, shares, heldShares: held.shares, estimatedAmount, destination: account, window, warnings };
264
+ }
265
+ // ── Write requests (pure) ───────────────────────────────────────────────
266
+ export function buildVaultDepositRequest(vault, amount, identity, opts) {
267
+ return buildPresigned({
268
+ type: "deposit_to_lake", path: "/lake/deposit", identity, timestamp: opts.timestamp, expiryWindow: opts.expiryWindow,
269
+ payload: { lake: vault, amount, idempotency_key: opts.idempotencyKey },
270
+ });
271
+ }
272
+ export function buildVaultWithdrawRequest(vault, shares, identity, opts) {
273
+ return buildPresigned({
274
+ type: "withdraw_from_lake", path: "/lake/withdraw", identity, timestamp: opts.timestamp, expiryWindow: opts.expiryWindow,
275
+ payload: { lake: vault, shares, idempotency_key: opts.idempotencyKey },
276
+ });
277
+ }
@@ -1,14 +1,18 @@
1
+ import { type FundingHistoryRow } from "./interface.js";
1
2
  import { Keypair } from "@solana/web3.js";
2
3
  import { PacificaClient, type Network } from "../pacifica/index.js";
3
- import type { ExchangeAdapter, ExchangeMarketInfo, ExchangePosition, ExchangeOrder, ExchangeBalance, ExchangeTrade, ExchangeFundingPayment, ExchangeKline } from "./interface.js";
4
+ import type { ExchangeAdapter, ExchangeMarketInfo, ExchangePosition, ExchangeOrder, ExchangeBalance, ExchangeTrade, ExchangePublicTrade, ExchangeFundingPayment, ExchangeKline } from "./interface.js";
4
5
  import type { ResolvedSlippage } from "./slippage.js";
5
6
  import type { SolanaSigner } from "../signer/index.js";
6
7
  import type { AgentMeta } from "../settings.js";
8
+ import type { PriceInfo } from "../pacifica/types/market.js";
9
+ import type { Position } from "../pacifica/types/position.js";
10
+ import type { AccountInfo } from "../pacifica/types/account.js";
7
11
  import type { TimeInForce as PacificaTif } from "../pacifica/types/order.js";
8
12
  import type { IocOutcome } from "./ioc-outcome.js";
9
13
  import { type BuilderApproval, type BuilderDecision, type BuilderFeeGate, type BuilderTarget } from "./builder-fee.js";
10
14
  /**
11
- * CLI TIF → Pacifica TIF (design §13.3). GTC / IOC / ALO / TOB are native; venue
15
+ * CLI TIF → Pacifica TIF. GTC / IOC / ALO / TOB are native; venue
12
16
  * aliases GTT → GTC and GTX → ALO; no TIF → GTC (uniform default). FOK (never
13
17
  * emulated) and unknown values → uniform CAPABILITY_UNSUPPORTED.
14
18
  */
@@ -114,6 +118,7 @@ export declare const PACIFICA_WITHDRAW_MIN_USDC = "1";
114
118
  * else (other status, unparseable body, already a PerpError) → `e` unchanged (outcome unknown).
115
119
  */
116
120
  export declare function pacificaWithdrawRejection(e: unknown, amount: string): unknown;
121
+ /** A POST the venue refused with HTTP 4xx — incl. RATE_LIMITED (429 / pre-send throttle, nothing sent). */
117
122
  export declare function pacificaRefused(e: unknown): boolean;
118
123
  /** A cancel the venue refused (HTTP 4xx), settled from the order's own history_by_id rows. */
119
124
  export type PacificaCancelRefusal = {
@@ -154,8 +159,49 @@ export interface PacificaAmendResult {
154
159
  notes: string[];
155
160
  venueRaw: unknown;
156
161
  }
162
+ /** GET /trades answers the last 20 fills (40 taker + maker rows); no limit or cursor. */
163
+ export declare const PACIFICA_TRADES_CAP = 20;
164
+ /** GET /funding_rate/history `limit` maximum per request (docs; live 4001 → 4000). */
165
+ export declare const PACIFICA_FUNDING_PAGE = 4000;
166
+ /** GET /kline: "Max range: 4000 candles" per request (HTTP 400 beyond, live 2026-10-19). */
167
+ export declare const PACIFICA_KLINE_MAX_BARS = 4000;
168
+ /** Requests one funding / kline read may send (the venue meters reads by credits). */
169
+ export declare const PACIFICA_MAX_PAGES = 10;
170
+ /**
171
+ * GET /kline intervals (venue error text, live 2026-10-19: "Must be one of 1m, 3m, 5m, 15m, 30m,
172
+ * 1h, 2h, 4h, 8h, 12h, 1d, 1w, 1M"; each answered 200 with rows labelled `i` = the interval).
173
+ * The ms length sizes the 4000-bar request windows (1M: 31 days, the longest month).
174
+ */
175
+ export declare const PACIFICA_KLINE_INTERVALS: Readonly<Record<string, number>>;
157
176
  /** Pacifica order_type of a stop / TP / SL order (stop_market, stop_limit, take_profit_*, stop_loss_*). */
158
177
  export declare function isPacificaStopType(type: string): boolean;
178
+ /**
179
+ * Trade direction of a Pacifica fill `side` (position effect): open_long / close_short buy,
180
+ * open_short / close_long sell; bid / ask for rows that carry an order side. Anything else →
181
+ * EXCHANGE_ERROR (never a guessed direction). Used by the public tape and the account fills.
182
+ */
183
+ export declare function pacificaFillSide(side: string, endpoint: string): "buy" | "sell";
184
+ /** Pacifica balance with its extras (USDC balance / loan, pending interest, withdrawable). */
185
+ export type PacificaBalance = ExchangeBalance & {
186
+ usdcBalance: string;
187
+ borrowedUsdc: string;
188
+ pendingInterest: string | null;
189
+ availableToWithdraw: string;
190
+ };
191
+ /**
192
+ * Balance of a Pacifica account from GET /account, its positions and /info/prices — the one
193
+ * implementation behind PacificaAdapter.getBalance() and the keyless `account balance --address`.
194
+ */
195
+ export declare function pacificaBalanceOf(info: AccountInfo, positions: Position[], prices: PriceInfo[]): PacificaBalance;
196
+ /**
197
+ * Open positions of one Pacifica account (`GET /positions?account=`), marked with `/info/prices`.
198
+ * The ONE mapper of the keyed `getPositions` and the public-address read: unresolved leverage is
199
+ * read from the account's `/account/settings` (public, by address), then the market max.
200
+ */
201
+ export declare function pacificaPositionRows(positions: Position[], prices: PriceInfo[], deps: {
202
+ accountSettings: () => Promise<unknown>;
203
+ maxLeverage: () => Promise<Map<string, number | null>>;
204
+ }): Promise<ExchangePosition[]>;
159
205
  export declare class PacificaAdapter implements ExchangeAdapter {
160
206
  readonly name = "pacifica";
161
207
  readonly chain = "solana";
@@ -179,6 +225,7 @@ export declare class PacificaAdapter implements ExchangeAdapter {
179
225
  private signMessage;
180
226
  private _marketsCache;
181
227
  private _marketsCacheTime;
228
+ private _infoCache;
182
229
  private static readonly CACHE_TTL;
183
230
  /** Venue network — part of every account cache key (the same key exists on mainnet and testnet). */
184
231
  private _network;
@@ -213,6 +260,17 @@ export declare class PacificaAdapter implements ExchangeAdapter {
213
260
  * mint) — never the agent, which cannot move funds.
214
261
  */
215
262
  masterSolanaSigner(): SolanaSigner;
263
+ /**
264
+ * The active signer for an account request whose body the caller builds itself (Print / vault
265
+ * writes): `account` (master address) and `agentWallet` (agent pubkey, or null when the master
266
+ * signs). Resolving it signs nothing. NO_SIGNER_AVAILABLE / AGENT_EXPIRED as `_resolveSigner`.
267
+ */
268
+ signingIdentity(): {
269
+ tier: "agent" | "master" | "pk";
270
+ account: string;
271
+ agentWallet: string | null;
272
+ signMessage: (msg: Uint8Array) => Promise<Uint8Array>;
273
+ };
216
274
  /** Access the underlying Keypair (only available with LocalSolanaSigner). */
217
275
  get keypair(): Keypair;
218
276
  private _getPrices;
@@ -230,8 +288,37 @@ export declare class PacificaAdapter implements ExchangeAdapter {
230
288
  */
231
289
  builderApprovalOf(target: BuilderTarget): Promise<BuilderApproval>;
232
290
  get sdk(): PacificaClient;
291
+ /**
292
+ * The configured account for an account read (settings, TWAP orders, …): no Pacifica key
293
+ * configured → NO_SIGNER_AVAILABLE. A keyless adapter holds a generated throwaway keypair, whose
294
+ * empty account would otherwise read as "no settings / no orders".
295
+ */
296
+ accountForReads(): string;
233
297
  get signer(): (msg: Uint8Array) => Promise<Uint8Array>;
298
+ /** GET /info rows (every instrument type), one CACHE_TTL cache for symbol resolution and getMarkets. */
299
+ private infoRows;
234
300
  getMarkets(): Promise<ExchangeMarketInfo[]>;
301
+ /**
302
+ * The venue's own spelling of a perp market typed by the user. Pacifica's API is
303
+ * case-sensitive (kBONK / kPEPE / kSHIB: `KPEPE` answers `200 []` on /trades, /kline and
304
+ * /funding_rate/history and 400 "Book not found" on /book — live 2026-10-19), and the CLI
305
+ * upper-cases the argument. Matched against /info exactly first, then case-insensitively
306
+ * (a "-PERP" display suffix ignored), as `market info` does. A listed non-perp (spot SOL-USDC)
307
+ * is refused before any request: this adapter serves perps only (isPacificaPerpetual).
308
+ */
309
+ wireSymbol(symbol: string): Promise<string>;
310
+ /**
311
+ * wireSymbol for an order entry point (market / limit / stop / edit): a resolution failure is
312
+ * a definite "not sent" (orderNotSent re-types a read error), never a retryable code.
313
+ */
314
+ private orderSymbol;
315
+ /**
316
+ * The venue's spelling for a cancel / TP-SL on an existing order or position: resolved as in
317
+ * wireSymbol when /info lists it (any instrument type, case-insensitive); otherwise — not listed
318
+ * (a delisted market) or /info unreadable — sent as typed: a cancel must still reach the venue,
319
+ * whose own answer is final.
320
+ */
321
+ private listedSymbol;
235
322
  getOrderbook(symbol: string): Promise<{
236
323
  bids: [string, string][];
237
324
  asks: [string, string][];
@@ -251,7 +338,7 @@ export declare class PacificaAdapter implements ExchangeAdapter {
251
338
  clientOrderId?: string;
252
339
  }): Promise<unknown>;
253
340
  /**
254
- * Venue-final outcome of a raw marketOrder() result (IocOutcomeCapable, design §13.10 #4),
341
+ * Venue-final outcome of a raw marketOrder() result (IocOutcomeCapable),
255
342
  * parsed from the result's content (so copies of it work): its `fillReport` — the terminal
256
343
  * history_by_id row (filled / cancelled / rejected) with a reported filled_amount — for the
257
344
  * same order id as the create response. null otherwise — reduce-only orders (not polled),
@@ -321,7 +408,7 @@ export declare class PacificaAdapter implements ExchangeAdapter {
321
408
  */
322
409
  editOrder(symbol: string, orderId: string, price: string, size: string): Promise<unknown>;
323
410
  /**
324
- * Amend that keeps the order's TIF (design §13.4, §13.10 #10). `size` = new open size.
411
+ * Amend that keeps the order's TIF. `size` = new open size.
325
412
  * TIF = `tif` when the caller gives one, else the TIF encoded in the order's generated
326
413
  * client_order_id; unknown → uniform CAPABILITY_UNSUPPORTED (never guessed).
327
414
  * - ALO: native edit (the venue re-creates the order as ALO, keeping its client_order_id).
@@ -368,12 +455,23 @@ export declare class PacificaAdapter implements ExchangeAdapter {
368
455
  assetId?: number;
369
456
  routeType?: number;
370
457
  }): Promise<unknown>;
371
- getRecentTrades(symbol: string, _limit?: number): Promise<ExchangeTrade[]>;
372
- getFundingHistory(symbol: string, limit?: number): Promise<{
373
- time: number;
374
- rate: string;
375
- price: string | null;
376
- }[]>;
458
+ /**
459
+ * Public tape (GET /trades). Every fill is listed TWICE — a `fulfill_taker` row and a
460
+ * `fulfill_maker` row, each with that party's position effect as `side` (live 2026-10-14:
461
+ * taker `open_short` paired with maker `close_short` at the same time / price / amount). The
462
+ * tape is the taker rows, with the taker's direction: open_long / close_short buy, open_short /
463
+ * close_long sell (the same mapping as the account fills, PACIFICA_FILL_*_SIDES). Was every row
464
+ * of both parties mapped through `side === "bid"` → all "sell". No de-duplication: two taker
465
+ * rows with equal time / price / amount are two fills (one order filling two makers).
466
+ */
467
+ getRecentTrades(symbol: string, limit?: number): Promise<ExchangePublicTrade[]>;
468
+ getFundingHistory(symbol: string, limit?: number): Promise<FundingHistoryRow[]>;
469
+ /**
470
+ * GET /kline over [startTime, endTime]. The venue refuses a range over 4000 candles (HTTP 400
471
+ * "Time range too large … Max range: 4000 candles"), so a longer window is read in consecutive
472
+ * 4000-bar windows (at most PACIFICA_MAX_PAGES), merged by open time. Intervals outside
473
+ * PACIFICA_KLINE_INTERVALS are refused locally with INVALID_PARAMS (the venue: HTTP 400).
474
+ */
377
475
  getKlines(symbol: string, interval: string, startTime: number, endTime: number): Promise<ExchangeKline[]>;
378
476
  /**
379
477
  * Recent orders, newest first (GET /orders/history; PacificaClient.get already unwraps the