@raintree-technology/perps 0.1.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 (316) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -0
  4. package/dist/adapters/aevo.d.ts +64 -0
  5. package/dist/adapters/aevo.js +899 -0
  6. package/dist/adapters/certification.d.ts +33 -0
  7. package/dist/adapters/certification.js +99 -0
  8. package/dist/adapters/decibel/order-manager.d.ts +45 -0
  9. package/dist/adapters/decibel/order-manager.js +140 -0
  10. package/dist/adapters/decibel/rest-client.d.ts +176 -0
  11. package/dist/adapters/decibel/rest-client.js +155 -0
  12. package/dist/adapters/decibel/ws-feed.d.ts +28 -0
  13. package/dist/adapters/decibel/ws-feed.js +166 -0
  14. package/dist/adapters/decibel.d.ts +108 -0
  15. package/dist/adapters/decibel.js +1377 -0
  16. package/dist/adapters/hyperliquid.d.ts +63 -0
  17. package/dist/adapters/hyperliquid.js +797 -0
  18. package/dist/adapters/index.d.ts +11 -0
  19. package/dist/adapters/index.js +12 -0
  20. package/dist/adapters/interface.d.ts +310 -0
  21. package/dist/adapters/interface.js +15 -0
  22. package/dist/adapters/orderly.d.ts +70 -0
  23. package/dist/adapters/orderly.js +936 -0
  24. package/dist/adapters/paradex.d.ts +69 -0
  25. package/dist/adapters/paradex.js +862 -0
  26. package/dist/adapters/utils.d.ts +17 -0
  27. package/dist/adapters/utils.js +122 -0
  28. package/dist/cli/command-metadata.d.ts +2 -0
  29. package/dist/cli/command-metadata.js +44 -0
  30. package/dist/cli/context.d.ts +14 -0
  31. package/dist/cli/context.js +59 -0
  32. package/dist/cli/experience.d.ts +48 -0
  33. package/dist/cli/experience.js +243 -0
  34. package/dist/cli/ink/app/AppShell.d.ts +12 -0
  35. package/dist/cli/ink/app/AppShell.js +32 -0
  36. package/dist/cli/ink/app/MetricStrip.d.ts +6 -0
  37. package/dist/cli/ink/app/MetricStrip.js +14 -0
  38. package/dist/cli/ink/app/Panel.d.ts +9 -0
  39. package/dist/cli/ink/app/Panel.js +7 -0
  40. package/dist/cli/ink/app/ascii.d.ts +2 -0
  41. package/dist/cli/ink/app/ascii.js +46 -0
  42. package/dist/cli/ink/app/index.d.ts +5 -0
  43. package/dist/cli/ink/app/index.js +4 -0
  44. package/dist/cli/ink/app/types.d.ts +15 -0
  45. package/dist/cli/ink/app/types.js +1 -0
  46. package/dist/cli/ink/components/PnL.d.ts +12 -0
  47. package/dist/cli/ink/components/PnL.js +23 -0
  48. package/dist/cli/ink/components/Spinner.d.ts +13 -0
  49. package/dist/cli/ink/components/Spinner.js +13 -0
  50. package/dist/cli/ink/components/Table.d.ts +14 -0
  51. package/dist/cli/ink/components/Table.js +42 -0
  52. package/dist/cli/ink/components/WatchHeader.d.ts +10 -0
  53. package/dist/cli/ink/components/WatchHeader.js +18 -0
  54. package/dist/cli/ink/components/index.d.ts +4 -0
  55. package/dist/cli/ink/components/index.js +4 -0
  56. package/dist/cli/ink/index.d.ts +4 -0
  57. package/dist/cli/ink/index.js +4 -0
  58. package/dist/cli/ink/render.d.ts +12 -0
  59. package/dist/cli/ink/render.js +21 -0
  60. package/dist/cli/ink/theme.d.ts +29 -0
  61. package/dist/cli/ink/theme.js +40 -0
  62. package/dist/cli/network-defaults.d.ts +10 -0
  63. package/dist/cli/network-defaults.js +35 -0
  64. package/dist/cli/output.d.ts +11 -0
  65. package/dist/cli/output.js +115 -0
  66. package/dist/cli/program.d.ts +18 -0
  67. package/dist/cli/program.js +164 -0
  68. package/dist/cli/watch.d.ts +19 -0
  69. package/dist/cli/watch.js +35 -0
  70. package/dist/client/index.d.ts +55 -0
  71. package/dist/client/index.js +157 -0
  72. package/dist/commands/account/add.d.ts +2 -0
  73. package/dist/commands/account/add.js +510 -0
  74. package/dist/commands/account/balances-simple.d.ts +5 -0
  75. package/dist/commands/account/balances-simple.js +63 -0
  76. package/dist/commands/account/index.d.ts +2 -0
  77. package/dist/commands/account/index.js +17 -0
  78. package/dist/commands/account/ls.d.ts +2 -0
  79. package/dist/commands/account/ls.js +95 -0
  80. package/dist/commands/account/positions-simple.d.ts +5 -0
  81. package/dist/commands/account/positions-simple.js +77 -0
  82. package/dist/commands/account/remove.d.ts +2 -0
  83. package/dist/commands/account/remove.js +47 -0
  84. package/dist/commands/account/set-default.d.ts +2 -0
  85. package/dist/commands/account/set-default.js +47 -0
  86. package/dist/commands/agent/index.d.ts +2 -0
  87. package/dist/commands/agent/index.js +126 -0
  88. package/dist/commands/arb/alert.d.ts +6 -0
  89. package/dist/commands/arb/alert.js +88 -0
  90. package/dist/commands/arb/basis-execute.d.ts +6 -0
  91. package/dist/commands/arb/basis-execute.js +332 -0
  92. package/dist/commands/arb/basis.d.ts +6 -0
  93. package/dist/commands/arb/basis.js +181 -0
  94. package/dist/commands/arb/compare.d.ts +6 -0
  95. package/dist/commands/arb/compare.js +216 -0
  96. package/dist/commands/arb/execute.d.ts +6 -0
  97. package/dist/commands/arb/execute.js +467 -0
  98. package/dist/commands/arb/funding.d.ts +6 -0
  99. package/dist/commands/arb/funding.js +201 -0
  100. package/dist/commands/arb/history.d.ts +6 -0
  101. package/dist/commands/arb/history.js +153 -0
  102. package/dist/commands/arb/index.d.ts +6 -0
  103. package/dist/commands/arb/index.js +29 -0
  104. package/dist/commands/arb/positions.d.ts +6 -0
  105. package/dist/commands/arb/positions.js +158 -0
  106. package/dist/commands/arb/spread.d.ts +6 -0
  107. package/dist/commands/arb/spread.js +253 -0
  108. package/dist/commands/arb/track.d.ts +6 -0
  109. package/dist/commands/arb/track.js +259 -0
  110. package/dist/commands/asset/book-simple.d.ts +5 -0
  111. package/dist/commands/asset/book-simple.js +77 -0
  112. package/dist/commands/asset/index.d.ts +2 -0
  113. package/dist/commands/asset/index.js +5 -0
  114. package/dist/commands/completion.d.ts +2 -0
  115. package/dist/commands/completion.js +161 -0
  116. package/dist/commands/config/index.d.ts +5 -0
  117. package/dist/commands/config/index.js +109 -0
  118. package/dist/commands/data/index.d.ts +31 -0
  119. package/dist/commands/data/index.js +1466 -0
  120. package/dist/commands/doctor.d.ts +2 -0
  121. package/dist/commands/doctor.js +201 -0
  122. package/dist/commands/exchange/index.d.ts +2 -0
  123. package/dist/commands/exchange/index.js +107 -0
  124. package/dist/commands/index.d.ts +2 -0
  125. package/dist/commands/index.js +48 -0
  126. package/dist/commands/markets/index.d.ts +2 -0
  127. package/dist/commands/markets/index.js +5 -0
  128. package/dist/commands/markets/ls-simple.d.ts +7 -0
  129. package/dist/commands/markets/ls-simple.js +277 -0
  130. package/dist/commands/operator/index.d.ts +2 -0
  131. package/dist/commands/operator/index.js +146 -0
  132. package/dist/commands/order/cancel-simple.d.ts +5 -0
  133. package/dist/commands/order/cancel-simple.js +104 -0
  134. package/dist/commands/order/index.d.ts +2 -0
  135. package/dist/commands/order/index.js +13 -0
  136. package/dist/commands/order/limit-simple.d.ts +5 -0
  137. package/dist/commands/order/limit-simple.js +195 -0
  138. package/dist/commands/order/market-simple.d.ts +5 -0
  139. package/dist/commands/order/market-simple.js +190 -0
  140. package/dist/commands/order/shared.d.ts +17 -0
  141. package/dist/commands/order/shared.js +51 -0
  142. package/dist/commands/order/trigger-simple.d.ts +5 -0
  143. package/dist/commands/order/trigger-simple.js +246 -0
  144. package/dist/commands/referral/index.d.ts +2 -0
  145. package/dist/commands/referral/index.js +7 -0
  146. package/dist/commands/referral/set.d.ts +2 -0
  147. package/dist/commands/referral/set.js +26 -0
  148. package/dist/commands/referral/status.d.ts +2 -0
  149. package/dist/commands/referral/status.js +31 -0
  150. package/dist/commands/replay/index.d.ts +2 -0
  151. package/dist/commands/replay/index.js +152 -0
  152. package/dist/commands/risk/analytics.d.ts +2 -0
  153. package/dist/commands/risk/analytics.js +64 -0
  154. package/dist/commands/risk/audit.d.ts +2 -0
  155. package/dist/commands/risk/audit.js +52 -0
  156. package/dist/commands/risk/index.d.ts +2 -0
  157. package/dist/commands/risk/index.js +9 -0
  158. package/dist/commands/risk/rules.d.ts +2 -0
  159. package/dist/commands/risk/rules.js +102 -0
  160. package/dist/commands/server.d.ts +2 -0
  161. package/dist/commands/server.js +208 -0
  162. package/dist/commands/setup/index.d.ts +2 -0
  163. package/dist/commands/setup/index.js +478 -0
  164. package/dist/commands/signal/index.d.ts +2 -0
  165. package/dist/commands/signal/index.js +129 -0
  166. package/dist/commands/state/index.d.ts +2 -0
  167. package/dist/commands/state/index.js +5 -0
  168. package/dist/commands/state/show.d.ts +2 -0
  169. package/dist/commands/state/show.js +105 -0
  170. package/dist/commands/strategy/index.d.ts +4 -0
  171. package/dist/commands/strategy/index.js +73 -0
  172. package/dist/commands/traces/index.d.ts +2 -0
  173. package/dist/commands/traces/index.js +76 -0
  174. package/dist/commands/ui/demo.d.ts +9 -0
  175. package/dist/commands/ui/demo.js +195 -0
  176. package/dist/commands/ui/index.d.ts +2 -0
  177. package/dist/commands/ui/index.js +7 -0
  178. package/dist/commands/ui/terminal.d.ts +2 -0
  179. package/dist/commands/ui/terminal.js +255 -0
  180. package/dist/commands/upgrade.d.ts +2 -0
  181. package/dist/commands/upgrade.js +98 -0
  182. package/dist/index.d.ts +2 -0
  183. package/dist/index.js +4 -0
  184. package/dist/lib/agent/audit.d.ts +12 -0
  185. package/dist/lib/agent/audit.js +13 -0
  186. package/dist/lib/agent/gateway.d.ts +13 -0
  187. package/dist/lib/agent/gateway.js +598 -0
  188. package/dist/lib/agent/metrics.d.ts +33 -0
  189. package/dist/lib/agent/metrics.js +175 -0
  190. package/dist/lib/agent/signature.d.ts +8 -0
  191. package/dist/lib/agent/signature.js +28 -0
  192. package/dist/lib/agent/tools.d.ts +28 -0
  193. package/dist/lib/agent/tools.js +453 -0
  194. package/dist/lib/agent/x402.d.ts +23 -0
  195. package/dist/lib/agent/x402.js +62 -0
  196. package/dist/lib/api-wallet.d.ts +69 -0
  197. package/dist/lib/api-wallet.js +101 -0
  198. package/dist/lib/balance-watcher.d.ts +25 -0
  199. package/dist/lib/balance-watcher.js +83 -0
  200. package/dist/lib/book-watcher.d.ts +25 -0
  201. package/dist/lib/book-watcher.js +48 -0
  202. package/dist/lib/config.d.ts +88 -0
  203. package/dist/lib/config.js +427 -0
  204. package/dist/lib/constants.d.ts +50 -0
  205. package/dist/lib/constants.js +84 -0
  206. package/dist/lib/contracts.d.ts +7 -0
  207. package/dist/lib/contracts.js +8 -0
  208. package/dist/lib/credential-vault.d.ts +22 -0
  209. package/dist/lib/credential-vault.js +109 -0
  210. package/dist/lib/db/accounts.d.ts +83 -0
  211. package/dist/lib/db/accounts.js +203 -0
  212. package/dist/lib/db/funding-history.d.ts +69 -0
  213. package/dist/lib/db/funding-history.js +183 -0
  214. package/dist/lib/db/index.d.ts +11 -0
  215. package/dist/lib/db/index.js +272 -0
  216. package/dist/lib/events/bus.d.ts +10 -0
  217. package/dist/lib/events/bus.js +17 -0
  218. package/dist/lib/events/types.d.ts +51 -0
  219. package/dist/lib/events/types.js +1 -0
  220. package/dist/lib/exchange.d.ts +30 -0
  221. package/dist/lib/exchange.js +84 -0
  222. package/dist/lib/execution/journal.d.ts +25 -0
  223. package/dist/lib/execution/journal.js +158 -0
  224. package/dist/lib/execution/safety.d.ts +34 -0
  225. package/dist/lib/execution/safety.js +197 -0
  226. package/dist/lib/exit-codes.d.ts +18 -0
  227. package/dist/lib/exit-codes.js +60 -0
  228. package/dist/lib/fetch.d.ts +18 -0
  229. package/dist/lib/fetch.js +66 -0
  230. package/dist/lib/fs-security.d.ts +10 -0
  231. package/dist/lib/fs-security.js +26 -0
  232. package/dist/lib/funding-tracker.d.ts +40 -0
  233. package/dist/lib/funding-tracker.js +118 -0
  234. package/dist/lib/logger.d.ts +27 -0
  235. package/dist/lib/logger.js +82 -0
  236. package/dist/lib/network-model.d.ts +13 -0
  237. package/dist/lib/network-model.js +30 -0
  238. package/dist/lib/onboarding.d.ts +133 -0
  239. package/dist/lib/onboarding.js +1459 -0
  240. package/dist/lib/operator-state.d.ts +25 -0
  241. package/dist/lib/operator-state.js +82 -0
  242. package/dist/lib/orders-watcher.d.ts +24 -0
  243. package/dist/lib/orders-watcher.js +74 -0
  244. package/dist/lib/paths.d.ts +20 -0
  245. package/dist/lib/paths.js +23 -0
  246. package/dist/lib/portfolio-watcher.d.ts +33 -0
  247. package/dist/lib/portfolio-watcher.js +95 -0
  248. package/dist/lib/position-watcher.d.ts +16 -0
  249. package/dist/lib/position-watcher.js +44 -0
  250. package/dist/lib/price-watcher.d.ts +15 -0
  251. package/dist/lib/price-watcher.js +84 -0
  252. package/dist/lib/prompts.d.ts +32 -0
  253. package/dist/lib/prompts.js +105 -0
  254. package/dist/lib/rate-limit.d.ts +32 -0
  255. package/dist/lib/rate-limit.js +88 -0
  256. package/dist/lib/risk/analytics.d.ts +39 -0
  257. package/dist/lib/risk/analytics.js +98 -0
  258. package/dist/lib/risk/drawdown.d.ts +18 -0
  259. package/dist/lib/risk/drawdown.js +49 -0
  260. package/dist/lib/risk/evaluation-log.d.ts +29 -0
  261. package/dist/lib/risk/evaluation-log.js +61 -0
  262. package/dist/lib/risk/index.d.ts +4 -0
  263. package/dist/lib/risk/index.js +4 -0
  264. package/dist/lib/risk/limits.d.ts +23 -0
  265. package/dist/lib/risk/limits.js +27 -0
  266. package/dist/lib/risk/manager.d.ts +32 -0
  267. package/dist/lib/risk/manager.js +85 -0
  268. package/dist/lib/risk/policy-middleware.d.ts +33 -0
  269. package/dist/lib/risk/policy-middleware.js +267 -0
  270. package/dist/lib/risk/position-sizer.d.ts +9 -0
  271. package/dist/lib/risk/position-sizer.js +14 -0
  272. package/dist/lib/risk/rules-store.d.ts +16 -0
  273. package/dist/lib/risk/rules-store.js +47 -0
  274. package/dist/lib/schema.d.ts +254 -0
  275. package/dist/lib/schema.js +199 -0
  276. package/dist/lib/secrets.d.ts +3 -0
  277. package/dist/lib/secrets.js +62 -0
  278. package/dist/lib/settings.d.ts +24 -0
  279. package/dist/lib/settings.js +86 -0
  280. package/dist/lib/signals.d.ts +73 -0
  281. package/dist/lib/signals.js +136 -0
  282. package/dist/lib/stable-stringify.d.ts +6 -0
  283. package/dist/lib/stable-stringify.js +17 -0
  284. package/dist/lib/state-context.d.ts +44 -0
  285. package/dist/lib/state-context.js +133 -0
  286. package/dist/lib/strategy/basis-trade.d.ts +2 -0
  287. package/dist/lib/strategy/basis-trade.js +24 -0
  288. package/dist/lib/strategy/funding-arb.d.ts +2 -0
  289. package/dist/lib/strategy/funding-arb.js +23 -0
  290. package/dist/lib/strategy/interface.d.ts +23 -0
  291. package/dist/lib/strategy/interface.js +1 -0
  292. package/dist/lib/strategy/registry.d.ts +4 -0
  293. package/dist/lib/strategy/registry.js +10 -0
  294. package/dist/lib/telemetry.d.ts +25 -0
  295. package/dist/lib/telemetry.js +101 -0
  296. package/dist/lib/trace-queries.d.ts +20 -0
  297. package/dist/lib/trace-queries.js +133 -0
  298. package/dist/lib/trace.d.ts +1 -0
  299. package/dist/lib/trace.js +4 -0
  300. package/dist/lib/trade-reputation.d.ts +6 -0
  301. package/dist/lib/trade-reputation.js +99 -0
  302. package/dist/lib/ui-tokens.d.ts +21 -0
  303. package/dist/lib/ui-tokens.js +26 -0
  304. package/dist/lib/validate.d.ts +39 -0
  305. package/dist/lib/validate.js +108 -0
  306. package/dist/lib/validation.d.ts +9 -0
  307. package/dist/lib/validation.js +64 -0
  308. package/dist/server/cache.d.ts +38 -0
  309. package/dist/server/cache.js +56 -0
  310. package/dist/server/index.d.ts +2 -0
  311. package/dist/server/index.js +89 -0
  312. package/dist/server/ipc.d.ts +18 -0
  313. package/dist/server/ipc.js +159 -0
  314. package/dist/server/subscriptions.d.ts +18 -0
  315. package/dist/server/subscriptions.js +114 -0
  316. package/package.json +124 -0
@@ -0,0 +1,23 @@
1
+ import type { IncomingMessage } from "node:http";
2
+ export interface X402Requirement {
3
+ protocol: "x402";
4
+ version: string;
5
+ payTo: string;
6
+ network: string;
7
+ asset: string;
8
+ amount: string;
9
+ timeoutSeconds: number;
10
+ }
11
+ export interface X402Receipt {
12
+ paymentId: string;
13
+ proofHash: string;
14
+ rawProof: string;
15
+ }
16
+ export interface X402ValidationResult {
17
+ ok: boolean;
18
+ receipt?: X402Receipt;
19
+ requirement?: X402Requirement;
20
+ error?: string;
21
+ }
22
+ export declare function getX402Requirement(): X402Requirement;
23
+ export declare function validateX402Payment(req: IncomingMessage): X402ValidationResult;
@@ -0,0 +1,62 @@
1
+ import { createHash } from "node:crypto";
2
+ function header(message, name) {
3
+ const value = message.headers[name];
4
+ if (Array.isArray(value)) {
5
+ return value[0];
6
+ }
7
+ if (typeof value === "string") {
8
+ return value;
9
+ }
10
+ return undefined;
11
+ }
12
+ export function getX402Requirement() {
13
+ return {
14
+ protocol: "x402",
15
+ version: "1",
16
+ payTo: (() => {
17
+ const addr = process.env.X402_PAY_TO;
18
+ if (!addr) {
19
+ console.warn("Warning: X402_PAY_TO is not set — payments will be sent to the zero address (burned).");
20
+ return "0x0000000000000000000000000000000000000000";
21
+ }
22
+ return addr;
23
+ })(),
24
+ network: process.env.X402_NETWORK ?? "base",
25
+ asset: process.env.X402_ASSET ?? "USDC",
26
+ amount: process.env.X402_AMOUNT ?? "0.05",
27
+ timeoutSeconds: Number(process.env.X402_TIMEOUT_SECONDS ?? 300),
28
+ };
29
+ }
30
+ export function validateX402Payment(req) {
31
+ const rawProof = header(req, "x402-payment") ??
32
+ header(req, "x-payment") ??
33
+ header(req, "payment");
34
+ if (!rawProof) {
35
+ return {
36
+ ok: false,
37
+ requirement: getX402Requirement(),
38
+ error: "missing_payment_proof",
39
+ };
40
+ }
41
+ const trimmed = rawProof.trim();
42
+ if (trimmed.length < 16) {
43
+ return {
44
+ ok: false,
45
+ requirement: getX402Requirement(),
46
+ error: "invalid_payment_proof",
47
+ };
48
+ }
49
+ const proofHash = createHash("sha256").update(trimmed).digest("hex");
50
+ const externalPaymentId = header(req, "x402-payment-id")?.trim();
51
+ const paymentId = externalPaymentId && externalPaymentId.length > 0
52
+ ? externalPaymentId
53
+ : `x402:${proofHash.slice(0, 24)}`;
54
+ return {
55
+ ok: true,
56
+ receipt: {
57
+ paymentId,
58
+ proofHash,
59
+ rawProof: trimmed,
60
+ },
61
+ };
62
+ }
@@ -0,0 +1,69 @@
1
+ import type { Address, Hex } from "viem";
2
+ /**
3
+ * Result of validating an API key
4
+ */
5
+ export type ValidateApiKeyResult = {
6
+ valid: true;
7
+ masterAddress: Address;
8
+ apiWalletAddress: Address;
9
+ } | {
10
+ valid: false;
11
+ error: string;
12
+ };
13
+ /**
14
+ * Validate an API private key by checking if it's registered as an agent wallet
15
+ * Returns the master address if valid, or an error message if not
16
+ */
17
+ export declare function validateApiKey(apiPrivateKey: Hex, isTestnet?: boolean): Promise<ValidateApiKeyResult>;
18
+ /**
19
+ * API wallet credentials
20
+ */
21
+ export interface ApiWalletCredentials {
22
+ privateKey: Hex;
23
+ publicKey: Address;
24
+ }
25
+ /**
26
+ * Generate a new API wallet (random private key)
27
+ */
28
+ export declare function generateApiWallet(): ApiWalletCredentials;
29
+ /**
30
+ * User role response types from Hyperliquid API
31
+ */
32
+ export type UserRoleResponse = {
33
+ role: "missing" | "user" | "vault";
34
+ } | {
35
+ role: "agent";
36
+ data: {
37
+ user: Address;
38
+ };
39
+ } | {
40
+ role: "subAccount";
41
+ data: {
42
+ master: Address;
43
+ };
44
+ };
45
+ /**
46
+ * Check if an API wallet is approved as an agent for a user
47
+ */
48
+ export declare function checkApiWalletApproval(apiWalletAddress: Address, userAddress: Address, isTestnet?: boolean): Promise<{
49
+ approved: boolean;
50
+ masterAddress?: Address;
51
+ }>;
52
+ /**
53
+ * Get the Hyperliquid API approval URL
54
+ */
55
+ export declare function getApprovalUrl(isTestnet?: boolean): string;
56
+ /**
57
+ * Poll for API wallet approval with timeout
58
+ * Returns true if approved, false if timed out
59
+ */
60
+ export declare function waitForApproval(apiWalletAddress: Address, userAddress: Address, isTestnet?: boolean, pollIntervalMs?: number, maxAttempts?: number): Promise<boolean>;
61
+ /**
62
+ * Get all extra agents (API wallets) for a user address
63
+ */
64
+ export interface ExtraAgent {
65
+ address: Address;
66
+ name: string;
67
+ validUntil: number;
68
+ }
69
+ export declare function getExtraAgents(userAddress: Address, isTestnet?: boolean): Promise<ExtraAgent[]>;
@@ -0,0 +1,101 @@
1
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
2
+ import { HttpTransport, InfoClient } from "@nktkas/hyperliquid";
3
+ /**
4
+ * Validate an API private key by checking if it's registered as an agent wallet
5
+ * Returns the master address if valid, or an error message if not
6
+ */
7
+ export async function validateApiKey(apiPrivateKey, isTestnet = false) {
8
+ const account = privateKeyToAccount(apiPrivateKey);
9
+ const apiWalletAddress = account.address;
10
+ const transport = new HttpTransport({ isTestnet });
11
+ const client = new InfoClient({ transport });
12
+ try {
13
+ const response = (await client.userRole({ user: apiWalletAddress }));
14
+ if (response.role === "agent") {
15
+ return {
16
+ valid: true,
17
+ masterAddress: response.data.user,
18
+ apiWalletAddress,
19
+ };
20
+ }
21
+ if (response.role === "missing") {
22
+ return { valid: false, error: "This key is not registered as an API wallet on Hyperliquid" };
23
+ }
24
+ return { valid: false, error: `Invalid role: ${response.role}. Expected an agent wallet.` };
25
+ }
26
+ catch (err) {
27
+ return { valid: false, error: `Failed to validate API key: ${err instanceof Error ? err.message : String(err)}` };
28
+ }
29
+ }
30
+ /**
31
+ * Generate a new API wallet (random private key)
32
+ */
33
+ export function generateApiWallet() {
34
+ const privateKey = generatePrivateKey();
35
+ const account = privateKeyToAccount(privateKey);
36
+ return {
37
+ privateKey,
38
+ publicKey: account.address,
39
+ };
40
+ }
41
+ /**
42
+ * Check if an API wallet is approved as an agent for a user
43
+ */
44
+ export async function checkApiWalletApproval(apiWalletAddress, userAddress, isTestnet = false) {
45
+ const transport = new HttpTransport({ isTestnet });
46
+ const client = new InfoClient({ transport });
47
+ try {
48
+ const response = await client.userRole({ user: apiWalletAddress });
49
+ if (response.role === "agent") {
50
+ // Check if the agent is approved for the specified user
51
+ const isApprovedForUser = response.data.user.toLowerCase() === userAddress.toLowerCase();
52
+ return {
53
+ approved: isApprovedForUser,
54
+ masterAddress: response.data.user,
55
+ };
56
+ }
57
+ return { approved: false };
58
+ }
59
+ catch {
60
+ return { approved: false };
61
+ }
62
+ }
63
+ /**
64
+ * Get the Hyperliquid API approval URL
65
+ */
66
+ export function getApprovalUrl(isTestnet = false) {
67
+ return isTestnet
68
+ ? "https://app.hyperliquid-testnet.xyz/API"
69
+ : "https://app.hyperliquid.xyz/API";
70
+ }
71
+ /**
72
+ * Poll for API wallet approval with timeout
73
+ * Returns true if approved, false if timed out
74
+ */
75
+ export async function waitForApproval(apiWalletAddress, userAddress, isTestnet = false, pollIntervalMs = 3000, maxAttempts = 100 // About 5 minutes with 3s interval
76
+ ) {
77
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
78
+ const result = await checkApiWalletApproval(apiWalletAddress, userAddress, isTestnet);
79
+ if (result.approved) {
80
+ return true;
81
+ }
82
+ // Wait before next poll
83
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
84
+ }
85
+ return false;
86
+ }
87
+ export async function getExtraAgents(userAddress, isTestnet = false) {
88
+ const transport = new HttpTransport({ isTestnet });
89
+ const client = new InfoClient({ transport });
90
+ try {
91
+ const response = await client.extraAgents({ user: userAddress });
92
+ return response.map((agent) => ({
93
+ address: agent.address,
94
+ name: agent.name,
95
+ validUntil: agent.validUntil,
96
+ }));
97
+ }
98
+ catch {
99
+ return [];
100
+ }
101
+ }
@@ -0,0 +1,25 @@
1
+ import type { Address } from "viem";
2
+ export interface BalanceData {
3
+ spotBalances: Array<{
4
+ token: string;
5
+ total: string;
6
+ hold: string;
7
+ available: string;
8
+ }>;
9
+ perpBalance: string;
10
+ }
11
+ export interface BalanceWatcher {
12
+ start(): Promise<void>;
13
+ stop(): Promise<void>;
14
+ }
15
+ export interface BalanceWatcherConfig {
16
+ user: Address;
17
+ isTestnet: boolean;
18
+ onUpdate: (data: BalanceData) => void;
19
+ onError: (error: Error) => void;
20
+ }
21
+ /**
22
+ * Creates a balance watcher that subscribes to clearinghouse state updates
23
+ * and polls spot balances on each update
24
+ */
25
+ export declare function createBalanceWatcher(config: BalanceWatcherConfig): BalanceWatcher;
@@ -0,0 +1,83 @@
1
+ import { WebSocketTransport, SubscriptionClient, HttpTransport, InfoClient } from "@nktkas/hyperliquid";
2
+ import WebSocket from "ws";
3
+ /**
4
+ * Creates a balance watcher that subscribes to clearinghouse state updates
5
+ * and polls spot balances on each update
6
+ */
7
+ export function createBalanceWatcher(config) {
8
+ let wsTransport = null;
9
+ let subscriptionClient = null;
10
+ let perpSubscription = null;
11
+ let httpClient = null;
12
+ return {
13
+ async start() {
14
+ // Create HTTP client for spot balance polling
15
+ const httpTransport = new HttpTransport({ isTestnet: config.isTestnet });
16
+ httpClient = new InfoClient({ transport: httpTransport });
17
+ // Fetch initial spot state
18
+ const spotState = await httpClient.spotClearinghouseState({ user: config.user });
19
+ let currentSpotBalances = spotState.balances
20
+ .filter((b) => parseFloat(b.total) !== 0)
21
+ .map((b) => ({
22
+ token: b.coin,
23
+ total: b.total,
24
+ hold: b.hold,
25
+ available: (parseFloat(b.total) - parseFloat(b.hold)).toString(),
26
+ }));
27
+ wsTransport = new WebSocketTransport({
28
+ isTestnet: config.isTestnet,
29
+ reconnect: { WebSocket: WebSocket },
30
+ });
31
+ subscriptionClient = new SubscriptionClient({ transport: wsTransport });
32
+ await wsTransport.ready();
33
+ // Subscribe to perp clearinghouse state
34
+ perpSubscription = await subscriptionClient.allDexsClearinghouseState({ user: config.user }, async (state) => {
35
+ const clearinghouseState = state.clearinghouseStates[0]?.[1];
36
+ const perpBalance = clearinghouseState?.marginSummary.accountValue || "0";
37
+ // Refresh spot balances on each perp update
38
+ if (httpClient) {
39
+ try {
40
+ const freshSpotState = await httpClient.spotClearinghouseState({ user: config.user });
41
+ currentSpotBalances = freshSpotState.balances
42
+ .filter((b) => parseFloat(b.total) !== 0)
43
+ .map((b) => ({
44
+ token: b.coin,
45
+ total: b.total,
46
+ hold: b.hold,
47
+ available: (parseFloat(b.total) - parseFloat(b.hold)).toString(),
48
+ }));
49
+ }
50
+ catch {
51
+ // Keep previous spot balances on error
52
+ }
53
+ }
54
+ config.onUpdate({
55
+ spotBalances: currentSpotBalances,
56
+ perpBalance,
57
+ });
58
+ });
59
+ },
60
+ async stop() {
61
+ if (perpSubscription) {
62
+ try {
63
+ await perpSubscription.unsubscribe();
64
+ }
65
+ catch {
66
+ // Ignore errors during unsubscribe
67
+ }
68
+ perpSubscription = null;
69
+ }
70
+ if (wsTransport) {
71
+ try {
72
+ await wsTransport.close();
73
+ }
74
+ catch {
75
+ // Ignore errors during close
76
+ }
77
+ wsTransport = null;
78
+ }
79
+ subscriptionClient = null;
80
+ httpClient = null;
81
+ },
82
+ };
83
+ }
@@ -0,0 +1,25 @@
1
+ export interface BookLevel {
2
+ px: string;
3
+ sz: string;
4
+ n: number;
5
+ }
6
+ export interface BookData {
7
+ coin: string;
8
+ bids: BookLevel[];
9
+ asks: BookLevel[];
10
+ time: number;
11
+ }
12
+ export interface BookWatcher {
13
+ start(): Promise<void>;
14
+ stop(): Promise<void>;
15
+ }
16
+ export interface BookWatcherConfig {
17
+ coin: string;
18
+ isTestnet: boolean;
19
+ onUpdate: (data: BookData) => void;
20
+ onError: (error: Error) => void;
21
+ }
22
+ /**
23
+ * Creates a book watcher that subscribes to L2 order book updates via WebSocket
24
+ */
25
+ export declare function createBookWatcher(config: BookWatcherConfig): BookWatcher;
@@ -0,0 +1,48 @@
1
+ import { WebSocketTransport, SubscriptionClient } from "@nktkas/hyperliquid";
2
+ import WebSocket from "ws";
3
+ /**
4
+ * Creates a book watcher that subscribes to L2 order book updates via WebSocket
5
+ */
6
+ export function createBookWatcher(config) {
7
+ let wsTransport = null;
8
+ let subscription = null;
9
+ return {
10
+ async start() {
11
+ wsTransport = new WebSocketTransport({
12
+ isTestnet: config.isTestnet,
13
+ reconnect: { WebSocket: WebSocket },
14
+ });
15
+ const subscriptionClient = new SubscriptionClient({ transport: wsTransport });
16
+ await wsTransport.ready();
17
+ subscription = await subscriptionClient.l2Book({ coin: config.coin }, (event) => {
18
+ const levels = event.levels;
19
+ config.onUpdate({
20
+ coin: config.coin,
21
+ bids: levels[0] || [],
22
+ asks: levels[1] || [],
23
+ time: event.time,
24
+ });
25
+ });
26
+ },
27
+ async stop() {
28
+ if (subscription) {
29
+ try {
30
+ await subscription.unsubscribe();
31
+ }
32
+ catch {
33
+ // Ignore errors during unsubscribe
34
+ }
35
+ subscription = null;
36
+ }
37
+ if (wsTransport) {
38
+ try {
39
+ await wsTransport.close();
40
+ }
41
+ catch {
42
+ // Ignore errors during close
43
+ }
44
+ wsTransport = null;
45
+ }
46
+ },
47
+ };
48
+ }
@@ -0,0 +1,88 @@
1
+ import type { Address, Hex } from "viem";
2
+ import type { ExchangeCredentials } from "../adapters/interface.js";
3
+ type ExchangeNetwork = "testnet" | "mainnet";
4
+ interface HyperliquidSettings {
5
+ network: ExchangeNetwork;
6
+ privateKey?: Hex;
7
+ walletAddress?: Address;
8
+ }
9
+ export interface DecibelCredentials {
10
+ apiWalletPrivateKey?: Hex;
11
+ apiWalletAddress?: string;
12
+ apiBearerToken?: string;
13
+ subaccountAddress?: string;
14
+ }
15
+ export interface DecibelSettings {
16
+ network: "testnet" | "mainnet";
17
+ fullnodeUrl: string;
18
+ restUrl: string;
19
+ wsUrl: string;
20
+ packageAddress: string;
21
+ credentials?: DecibelCredentials;
22
+ }
23
+ interface AevoSettings {
24
+ network: ExchangeNetwork;
25
+ restUrl: string;
26
+ apiKey?: string;
27
+ apiSecret?: string;
28
+ signingKey?: Hex;
29
+ }
30
+ interface OrderlySettings {
31
+ network: ExchangeNetwork;
32
+ restUrl: string;
33
+ accountId?: string;
34
+ key?: string;
35
+ secret?: string;
36
+ tradingKey?: string;
37
+ tradingSecret?: string;
38
+ }
39
+ interface ParadexSettings {
40
+ network: ExchangeNetwork;
41
+ restUrl: string;
42
+ apiBearerToken?: string;
43
+ account?: string;
44
+ ethereumAccount?: string;
45
+ privateKey?: string;
46
+ chainId?: string;
47
+ }
48
+ export interface RiskPolicyConfig {
49
+ maxPositionSizeUsd: number;
50
+ maxTotalExposureUsd: number;
51
+ maxLeverage: number;
52
+ minSignalConfidence: number;
53
+ maxDrawdownPct: number;
54
+ defaultLeverage: number;
55
+ }
56
+ export interface ExecutionSafetyConfig {
57
+ stopLossPct: number;
58
+ takeProfitPct: number;
59
+ spreadOffset: number;
60
+ }
61
+ export interface Config {
62
+ privateKey?: Hex;
63
+ walletAddress?: Address;
64
+ testnet: boolean;
65
+ account?: {
66
+ alias: string;
67
+ type: "readonly" | "api_wallet";
68
+ };
69
+ risk: RiskPolicyConfig;
70
+ executionSafety: ExecutionSafetyConfig;
71
+ operator: {
72
+ heartbeatIntervalMs: number;
73
+ };
74
+ exchanges: {
75
+ hyperliquid: HyperliquidSettings;
76
+ decibel: DecibelSettings;
77
+ aevo: AevoSettings;
78
+ orderly: OrderlySettings;
79
+ paradex: ParadexSettings;
80
+ };
81
+ }
82
+ export declare function loadConfig(testnet: boolean, exchangeId?: string): Config;
83
+ interface CredentialRequirement {
84
+ requireReadAccess?: boolean;
85
+ requireTrading?: boolean;
86
+ }
87
+ export declare function getExchangeCredentials(config: Config, exchangeId: string, requirement?: CredentialRequirement): ExchangeCredentials;
88
+ export {};