@nexstone/rift-cli 0.1.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 (137) hide show
  1. package/LICENSE +201 -0
  2. package/bin/run.js +22 -0
  3. package/dist/commands/algo.d.ts +32 -0
  4. package/dist/commands/algo.js +719 -0
  5. package/dist/commands/audit.d.ts +13 -0
  6. package/dist/commands/audit.js +37 -0
  7. package/dist/commands/auth-status.d.ts +14 -0
  8. package/dist/commands/auth-status.js +118 -0
  9. package/dist/commands/auth.d.ts +14 -0
  10. package/dist/commands/auth.js +275 -0
  11. package/dist/commands/backtest.d.ts +26 -0
  12. package/dist/commands/backtest.js +283 -0
  13. package/dist/commands/collect/start.d.ts +11 -0
  14. package/dist/commands/collect/start.js +78 -0
  15. package/dist/commands/collect/status.d.ts +6 -0
  16. package/dist/commands/collect/status.js +60 -0
  17. package/dist/commands/compare.d.ts +16 -0
  18. package/dist/commands/compare.js +130 -0
  19. package/dist/commands/config.d.ts +16 -0
  20. package/dist/commands/config.js +143 -0
  21. package/dist/commands/cost.d.ts +20 -0
  22. package/dist/commands/cost.js +104 -0
  23. package/dist/commands/cross-asset.d.ts +14 -0
  24. package/dist/commands/cross-asset.js +39 -0
  25. package/dist/commands/data/fetch.d.ts +15 -0
  26. package/dist/commands/data/fetch.js +82 -0
  27. package/dist/commands/data/list.d.ts +6 -0
  28. package/dist/commands/data/list.js +28 -0
  29. package/dist/commands/data-inventory.d.ts +9 -0
  30. package/dist/commands/data-inventory.js +24 -0
  31. package/dist/commands/deposit.d.ts +10 -0
  32. package/dist/commands/deposit.js +222 -0
  33. package/dist/commands/doctor.d.ts +6 -0
  34. package/dist/commands/doctor.js +87 -0
  35. package/dist/commands/funding-browser.d.ts +12 -0
  36. package/dist/commands/funding-browser.js +33 -0
  37. package/dist/commands/guide.d.ts +6 -0
  38. package/dist/commands/guide.js +15 -0
  39. package/dist/commands/home.d.ts +23 -0
  40. package/dist/commands/home.js +210 -0
  41. package/dist/commands/init.d.ts +7 -0
  42. package/dist/commands/init.js +122 -0
  43. package/dist/commands/install.d.ts +9 -0
  44. package/dist/commands/install.js +89 -0
  45. package/dist/commands/interactive.d.ts +17 -0
  46. package/dist/commands/interactive.js +179 -0
  47. package/dist/commands/lessons.d.ts +12 -0
  48. package/dist/commands/lessons.js +33 -0
  49. package/dist/commands/montecarlo.d.ts +19 -0
  50. package/dist/commands/montecarlo.js +168 -0
  51. package/dist/commands/more.d.ts +11 -0
  52. package/dist/commands/more.js +227 -0
  53. package/dist/commands/new.d.ts +14 -0
  54. package/dist/commands/new.js +306 -0
  55. package/dist/commands/pairs.d.ts +22 -0
  56. package/dist/commands/pairs.js +147 -0
  57. package/dist/commands/perp/close.d.ts +12 -0
  58. package/dist/commands/perp/close.js +57 -0
  59. package/dist/commands/perp/long.d.ts +14 -0
  60. package/dist/commands/perp/long.js +38 -0
  61. package/dist/commands/perp/short.d.ts +14 -0
  62. package/dist/commands/perp/short.js +27 -0
  63. package/dist/commands/perp/status.d.ts +9 -0
  64. package/dist/commands/perp/status.js +26 -0
  65. package/dist/commands/portfolio/alerts.d.ts +6 -0
  66. package/dist/commands/portfolio/alerts.js +47 -0
  67. package/dist/commands/portfolio/backtest.d.ts +12 -0
  68. package/dist/commands/portfolio/backtest.js +178 -0
  69. package/dist/commands/portfolio/create.d.ts +7 -0
  70. package/dist/commands/portfolio/create.js +195 -0
  71. package/dist/commands/portfolio/start.d.ts +9 -0
  72. package/dist/commands/portfolio/start.js +64 -0
  73. package/dist/commands/portfolio/status.d.ts +6 -0
  74. package/dist/commands/portfolio/status.js +128 -0
  75. package/dist/commands/portfolio/stop.d.ts +6 -0
  76. package/dist/commands/portfolio/stop.js +81 -0
  77. package/dist/commands/portfolio-backtest.d.ts +13 -0
  78. package/dist/commands/portfolio-backtest.js +37 -0
  79. package/dist/commands/portfolio-matrix.d.ts +12 -0
  80. package/dist/commands/portfolio-matrix.js +30 -0
  81. package/dist/commands/quick-test.d.ts +17 -0
  82. package/dist/commands/quick-test.js +45 -0
  83. package/dist/commands/research.d.ts +57 -0
  84. package/dist/commands/research.js +1976 -0
  85. package/dist/commands/scout.d.ts +14 -0
  86. package/dist/commands/scout.js +184 -0
  87. package/dist/commands/serve.d.ts +9 -0
  88. package/dist/commands/serve.js +1176 -0
  89. package/dist/commands/setup/proxy.d.ts +10 -0
  90. package/dist/commands/setup/proxy.js +267 -0
  91. package/dist/commands/spot/buy.d.ts +14 -0
  92. package/dist/commands/spot/buy.js +38 -0
  93. package/dist/commands/spot/sell.d.ts +14 -0
  94. package/dist/commands/spot/sell.js +39 -0
  95. package/dist/commands/strategies/list.d.ts +6 -0
  96. package/dist/commands/strategies/list.js +34 -0
  97. package/dist/commands/sweep.d.ts +19 -0
  98. package/dist/commands/sweep.js +137 -0
  99. package/dist/commands/sync.d.ts +17 -0
  100. package/dist/commands/sync.js +54 -0
  101. package/dist/commands/test-trade.d.ts +6 -0
  102. package/dist/commands/test-trade.js +97 -0
  103. package/dist/commands/trade.d.ts +26 -0
  104. package/dist/commands/trade.js +274 -0
  105. package/dist/commands/transfer.d.ts +13 -0
  106. package/dist/commands/transfer.js +65 -0
  107. package/dist/commands/verify.d.ts +16 -0
  108. package/dist/commands/verify.js +38 -0
  109. package/dist/commands/walkforward.d.ts +20 -0
  110. package/dist/commands/walkforward.js +191 -0
  111. package/dist/commands/withdraw.d.ts +12 -0
  112. package/dist/commands/withdraw.js +55 -0
  113. package/dist/commands/workbench-create.d.ts +13 -0
  114. package/dist/commands/workbench-create.js +39 -0
  115. package/dist/lib/account-mode.d.ts +44 -0
  116. package/dist/lib/account-mode.js +96 -0
  117. package/dist/lib/analyzer.d.ts +4 -0
  118. package/dist/lib/analyzer.js +62 -0
  119. package/dist/lib/base-command.d.ts +35 -0
  120. package/dist/lib/base-command.js +49 -0
  121. package/dist/lib/credentials.d.ts +46 -0
  122. package/dist/lib/credentials.js +137 -0
  123. package/dist/lib/engine-passthrough.d.ts +28 -0
  124. package/dist/lib/engine-passthrough.js +60 -0
  125. package/dist/lib/fees.d.ts +52 -0
  126. package/dist/lib/fees.js +97 -0
  127. package/dist/lib/python-bridge.d.ts +24 -0
  128. package/dist/lib/python-bridge.js +182 -0
  129. package/dist/lib/setup-status.d.ts +32 -0
  130. package/dist/lib/setup-status.js +121 -0
  131. package/dist/lib/status-footer.d.ts +35 -0
  132. package/dist/lib/status-footer.js +101 -0
  133. package/dist/lib/tui.d.ts +130 -0
  134. package/dist/lib/tui.js +300 -0
  135. package/dist/lib/walletconnect.d.ts +70 -0
  136. package/dist/lib/walletconnect.js +407 -0
  137. package/package.json +49 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * WalletConnect integration for wallet approvals and fund management.
3
+ *
4
+ * Used for:
5
+ * 1. Auth setup — ApproveAgent + ApproveBuilderFee (one-time)
6
+ * 2. Withdrawals — withdraw_from_bridge (occasional, needs main wallet)
7
+ * 3. Transfers — usdClassTransfer spot↔perps (occasional, needs main wallet)
8
+ * 4. Deposits — Arbitrum bridge interaction (occasional, needs main wallet)
9
+ *
10
+ * Sessions persist across CLI invocations via SQLite storage at ~/.rift/walletconnect.db.
11
+ * Trading uses the agent key locally — no WalletConnect needed per trade.
12
+ */
13
+ import SignClient from '@walletconnect/sign-client';
14
+ export interface ApprovalResult {
15
+ success: boolean;
16
+ signature?: string;
17
+ nonce?: number;
18
+ action?: Record<string, any>;
19
+ error?: string;
20
+ }
21
+ export interface WalletSession {
22
+ client: SignClient;
23
+ topic: string;
24
+ account: string;
25
+ }
26
+ /**
27
+ * Resume an existing WalletConnect session from disk.
28
+ * Returns null if no valid session exists (user needs to scan QR).
29
+ */
30
+ export declare function getExistingSession(): Promise<WalletSession | null>;
31
+ /**
32
+ * Connect a new wallet via QR code scan.
33
+ * Session persists automatically via SQLite storage.
34
+ */
35
+ export declare function connectWallet(onQRCode: (uri: string) => void, onStatus: (msg: string) => void): Promise<WalletSession>;
36
+ /**
37
+ * Request an EIP-712 signature via WalletConnect (persisted session).
38
+ * Sends push notification to user's phone. Returns null if no session.
39
+ */
40
+ export declare function requestSignature(typedData: Record<string, any>): Promise<string | null>;
41
+ /**
42
+ * Request ApproveAgent signature via WalletConnect.
43
+ */
44
+ export declare function requestAgentApproval(session: WalletSession, agentAddress: string, isMainnet?: boolean): Promise<ApprovalResult>;
45
+ /**
46
+ * Request ApproveBuilderFee signature via WalletConnect.
47
+ */
48
+ export declare function requestBuilderFeeApproval(session: WalletSession, isMainnet?: boolean): Promise<ApprovalResult>;
49
+ /**
50
+ * Request withdrawal signature via WalletConnect.
51
+ * User approves on phone, USDC bridges from HL to Arbitrum.
52
+ */
53
+ export declare function requestWithdrawal(amount: string, destination: string, isMainnet?: boolean): Promise<ApprovalResult>;
54
+ /**
55
+ * Request spot↔perps transfer signature via WalletConnect.
56
+ */
57
+ export declare function requestTransfer(amount: string, toPerp: boolean, isMainnet?: boolean): Promise<ApprovalResult>;
58
+ /**
59
+ * Post a signed action to Hyperliquid's exchange API.
60
+ */
61
+ export declare function postToHyperliquid(action: Record<string, any>, signature: string, nonce: number, isMainnet?: boolean): Promise<Record<string, any>>;
62
+ export declare const postApprovalToHyperliquid: typeof postToHyperliquid;
63
+ /**
64
+ * Display QR code in terminal.
65
+ */
66
+ export declare function showQRCode(uri: string): void;
67
+ /**
68
+ * Disconnect WalletConnect session (only if user explicitly requests).
69
+ */
70
+ export declare function disconnectWallet(session: WalletSession): Promise<void>;
@@ -0,0 +1,407 @@
1
+ /**
2
+ * WalletConnect integration for wallet approvals and fund management.
3
+ *
4
+ * Used for:
5
+ * 1. Auth setup — ApproveAgent + ApproveBuilderFee (one-time)
6
+ * 2. Withdrawals — withdraw_from_bridge (occasional, needs main wallet)
7
+ * 3. Transfers — usdClassTransfer spot↔perps (occasional, needs main wallet)
8
+ * 4. Deposits — Arbitrum bridge interaction (occasional, needs main wallet)
9
+ *
10
+ * Sessions persist across CLI invocations via SQLite storage at ~/.rift/walletconnect.db.
11
+ * Trading uses the agent key locally — no WalletConnect needed per trade.
12
+ */
13
+ import * as os from 'node:os';
14
+ import * as path from 'node:path';
15
+ import SignClient from '@walletconnect/sign-client';
16
+ // @ts-ignore — no types available for qrcode-terminal
17
+ import qrcode from 'qrcode-terminal';
18
+ import { BUILDER_ADDRESS, BUILDER_FEE_RATE } from './fees.js';
19
+ // Register at cloud.walletconnect.com — free tier
20
+ const WALLETCONNECT_PROJECT_ID = '315aa4af2eda0390c8411a5b5e9b4f7a';
21
+ // Persistent session storage
22
+ const WC_DB_PATH = path.join(os.homedir(), '.rift', 'walletconnect.db');
23
+ // Hyperliquid EIP-712 constants
24
+ const HL_SIGNATURE_CHAIN_ID = '0x66eee'; // 421614 decimal
25
+ const HL_SIGNATURE_CHAIN_ID_DECIMAL = parseInt(HL_SIGNATURE_CHAIN_ID, 16);
26
+ // Hyperliquid API URL (mainnet-only post-testnet rip)
27
+ const HL_MAINNET_API = 'https://api.hyperliquid.xyz';
28
+ // ─── SESSION MANAGEMENT ────────────────────────────────────
29
+ /**
30
+ * Get or create the SignClient with persistent SQLite storage.
31
+ * Sessions survive process restarts — no re-scan needed.
32
+ */
33
+ async function getSignClient() {
34
+ return SignClient.init({
35
+ projectId: WALLETCONNECT_PROJECT_ID,
36
+ metadata: {
37
+ name: 'RIFT',
38
+ description: 'Algorithmic trading engine for Hyperliquid',
39
+ url: 'https://nexstone.io',
40
+ icons: ['https://nexstone.io/nexstone-logo.png'],
41
+ },
42
+ storageOptions: {
43
+ database: WC_DB_PATH,
44
+ },
45
+ });
46
+ }
47
+ /**
48
+ * Resume an existing WalletConnect session from disk.
49
+ * Returns null if no valid session exists (user needs to scan QR).
50
+ */
51
+ export async function getExistingSession() {
52
+ try {
53
+ const client = await getSignClient();
54
+ const sessions = client.session.getAll();
55
+ const now = Math.floor(Date.now() / 1000);
56
+ const valid = sessions.find(s => s.expiry > now);
57
+ if (!valid)
58
+ return null;
59
+ // Auto-extend if expiring within 2 days
60
+ const twoDays = 2 * 24 * 60 * 60;
61
+ if (valid.expiry - now < twoDays) {
62
+ try {
63
+ await client.extend({ topic: valid.topic });
64
+ }
65
+ catch {
66
+ // Extension failed — session might be dead
67
+ }
68
+ }
69
+ // Verify connectivity
70
+ try {
71
+ await client.ping({ topic: valid.topic });
72
+ }
73
+ catch {
74
+ return null; // session dead — user needs to re-scan
75
+ }
76
+ // Extract account address
77
+ const accounts = valid.namespaces.eip155?.accounts || [];
78
+ const account = accounts.length > 0 ? accounts[0].split(':').pop() : '';
79
+ return { client, topic: valid.topic, account };
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ /**
86
+ * Connect a new wallet via QR code scan.
87
+ * Session persists automatically via SQLite storage.
88
+ */
89
+ export async function connectWallet(onQRCode, onStatus) {
90
+ onStatus('Initializing WalletConnect...');
91
+ const client = await getSignClient();
92
+ const { uri, approval } = await client.connect({
93
+ requiredNamespaces: {
94
+ eip155: {
95
+ methods: ['eth_signTypedData_v4', 'eth_signTypedData', 'eth_sendTransaction'],
96
+ chains: ['eip155:42161'], // Arbitrum
97
+ events: ['accountsChanged', 'chainChanged'],
98
+ },
99
+ },
100
+ });
101
+ if (!uri) {
102
+ throw new Error('Failed to generate WalletConnect URI');
103
+ }
104
+ onQRCode(uri);
105
+ const session = await approval();
106
+ const accounts = session.namespaces.eip155?.accounts || [];
107
+ if (accounts.length === 0) {
108
+ throw new Error('No accounts returned from wallet');
109
+ }
110
+ const account = accounts[0].split(':').pop();
111
+ return { client, topic: session.topic, account };
112
+ }
113
+ // ─── SIGNING REQUESTS ──────────────────────────────────────
114
+ /**
115
+ * Request an EIP-712 signature via WalletConnect (persisted session).
116
+ * Sends push notification to user's phone. Returns null if no session.
117
+ */
118
+ export async function requestSignature(typedData) {
119
+ const session = await getExistingSession();
120
+ if (!session)
121
+ return null;
122
+ try {
123
+ const result = await session.client.request({
124
+ topic: session.topic,
125
+ chainId: 'eip155:42161',
126
+ request: {
127
+ method: 'eth_signTypedData_v4',
128
+ params: [session.account, JSON.stringify(typedData)],
129
+ },
130
+ });
131
+ return result;
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
137
+ /**
138
+ * Request ApproveAgent signature via WalletConnect.
139
+ */
140
+ export async function requestAgentApproval(session, agentAddress, isMainnet = true) {
141
+ const nonce = Date.now();
142
+ const typedData = buildApproveAgentTypedData(agentAddress, nonce, isMainnet);
143
+ const action = {
144
+ type: 'approveAgent',
145
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
146
+ signatureChainId: HL_SIGNATURE_CHAIN_ID,
147
+ agentAddress,
148
+ agentName: '',
149
+ nonce,
150
+ };
151
+ try {
152
+ const signature = await session.client.request({
153
+ topic: session.topic,
154
+ chainId: 'eip155:42161',
155
+ request: {
156
+ method: 'eth_signTypedData_v4',
157
+ params: [session.account, JSON.stringify(typedData)],
158
+ },
159
+ });
160
+ return { success: true, signature, nonce, action };
161
+ }
162
+ catch (error) {
163
+ return { success: false, error: error?.message || 'User rejected signature' };
164
+ }
165
+ }
166
+ /**
167
+ * Request ApproveBuilderFee signature via WalletConnect.
168
+ */
169
+ export async function requestBuilderFeeApproval(session, isMainnet = true) {
170
+ const nonce = Date.now();
171
+ const typedData = buildApproveBuilderFeeTypedData(nonce, isMainnet);
172
+ const action = {
173
+ type: 'approveBuilderFee',
174
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
175
+ signatureChainId: HL_SIGNATURE_CHAIN_ID,
176
+ maxFeeRate: BUILDER_FEE_RATE,
177
+ builder: BUILDER_ADDRESS,
178
+ nonce,
179
+ };
180
+ try {
181
+ const signature = await session.client.request({
182
+ topic: session.topic,
183
+ chainId: 'eip155:42161',
184
+ request: {
185
+ method: 'eth_signTypedData_v4',
186
+ params: [session.account, JSON.stringify(typedData)],
187
+ },
188
+ });
189
+ return { success: true, signature, nonce, action };
190
+ }
191
+ catch (error) {
192
+ return { success: false, error: error?.message || 'User rejected signature' };
193
+ }
194
+ }
195
+ // ─── FUND MANAGEMENT SIGNING ───────────────────────────────
196
+ /**
197
+ * Request withdrawal signature via WalletConnect.
198
+ * User approves on phone, USDC bridges from HL to Arbitrum.
199
+ */
200
+ export async function requestWithdrawal(amount, destination, isMainnet = true) {
201
+ const nonce = Date.now();
202
+ const typedData = buildWithdrawTypedData(destination, amount, nonce, isMainnet);
203
+ const action = {
204
+ type: 'withdraw3',
205
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
206
+ signatureChainId: HL_SIGNATURE_CHAIN_ID,
207
+ destination,
208
+ amount,
209
+ time: nonce,
210
+ };
211
+ const session = await getExistingSession();
212
+ if (!session) {
213
+ return { success: false, error: 'No wallet connected. Run: rift auth setup' };
214
+ }
215
+ try {
216
+ const signature = await session.client.request({
217
+ topic: session.topic,
218
+ chainId: 'eip155:42161',
219
+ request: {
220
+ method: 'eth_signTypedData_v4',
221
+ params: [session.account, JSON.stringify(typedData)],
222
+ },
223
+ });
224
+ return { success: true, signature, nonce, action };
225
+ }
226
+ catch (error) {
227
+ return { success: false, error: error?.message || 'User rejected withdrawal' };
228
+ }
229
+ }
230
+ /**
231
+ * Request spot↔perps transfer signature via WalletConnect.
232
+ */
233
+ export async function requestTransfer(amount, toPerp, isMainnet = true) {
234
+ const nonce = Date.now();
235
+ const typedData = buildTransferTypedData(amount, toPerp, nonce, isMainnet);
236
+ const action = {
237
+ type: 'usdClassTransfer',
238
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
239
+ signatureChainId: HL_SIGNATURE_CHAIN_ID,
240
+ amount,
241
+ toPerp,
242
+ nonce,
243
+ };
244
+ const session = await getExistingSession();
245
+ if (!session) {
246
+ return { success: false, error: 'No wallet connected. Run: rift auth setup' };
247
+ }
248
+ try {
249
+ const signature = await session.client.request({
250
+ topic: session.topic,
251
+ chainId: 'eip155:42161',
252
+ request: {
253
+ method: 'eth_signTypedData_v4',
254
+ params: [session.account, JSON.stringify(typedData)],
255
+ },
256
+ });
257
+ return { success: true, signature, nonce, action };
258
+ }
259
+ catch (error) {
260
+ return { success: false, error: error?.message || 'User rejected transfer' };
261
+ }
262
+ }
263
+ // ─── POST TO HYPERLIQUID ───────────────────────────────────
264
+ /**
265
+ * Post a signed action to Hyperliquid's exchange API.
266
+ */
267
+ export async function postToHyperliquid(action, signature, nonce, isMainnet = true) {
268
+ const baseUrl = HL_MAINNET_API;
269
+ // Parse signature into r, s, v
270
+ const sigBytes = signature.startsWith('0x') ? signature.slice(2) : signature;
271
+ const r = '0x' + sigBytes.slice(0, 64);
272
+ const s = '0x' + sigBytes.slice(64, 128);
273
+ const v = parseInt(sigBytes.slice(128, 130), 16);
274
+ const response = await fetch(`${baseUrl}/exchange`, {
275
+ method: 'POST',
276
+ headers: { 'Content-Type': 'application/json' },
277
+ body: JSON.stringify({
278
+ action,
279
+ nonce,
280
+ signature: { r, s, v },
281
+ }),
282
+ });
283
+ if (!response.ok) {
284
+ const text = await response.text();
285
+ throw new Error(`Hyperliquid API error: ${response.status} — ${text}`);
286
+ }
287
+ return response.json();
288
+ }
289
+ // Legacy alias
290
+ export const postApprovalToHyperliquid = postToHyperliquid;
291
+ /**
292
+ * Display QR code in terminal.
293
+ */
294
+ export function showQRCode(uri) {
295
+ qrcode.generate(uri, { small: true });
296
+ }
297
+ /**
298
+ * Disconnect WalletConnect session (only if user explicitly requests).
299
+ */
300
+ export async function disconnectWallet(session) {
301
+ try {
302
+ await session.client.disconnect({
303
+ topic: session.topic,
304
+ reason: { code: 6000, message: 'User disconnected' },
305
+ });
306
+ }
307
+ catch {
308
+ // Ignore disconnect errors
309
+ }
310
+ }
311
+ // ─── EIP-712 TYPE BUILDERS ─────────────────────────────────
312
+ const HL_DOMAIN = {
313
+ name: 'HyperliquidSignTransaction',
314
+ version: '1',
315
+ chainId: HL_SIGNATURE_CHAIN_ID_DECIMAL,
316
+ verifyingContract: '0x0000000000000000000000000000000000000000',
317
+ };
318
+ const EIP712_DOMAIN_TYPE = [
319
+ { name: 'name', type: 'string' },
320
+ { name: 'version', type: 'string' },
321
+ { name: 'chainId', type: 'uint256' },
322
+ { name: 'verifyingContract', type: 'address' },
323
+ ];
324
+ function buildApproveAgentTypedData(agentAddress, nonce, isMainnet) {
325
+ return {
326
+ domain: HL_DOMAIN,
327
+ types: {
328
+ EIP712Domain: EIP712_DOMAIN_TYPE,
329
+ 'HyperliquidTransaction:ApproveAgent': [
330
+ { name: 'hyperliquidChain', type: 'string' },
331
+ { name: 'agentAddress', type: 'address' },
332
+ { name: 'agentName', type: 'string' },
333
+ { name: 'nonce', type: 'uint64' },
334
+ ],
335
+ },
336
+ primaryType: 'HyperliquidTransaction:ApproveAgent',
337
+ message: {
338
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
339
+ agentAddress,
340
+ agentName: '',
341
+ nonce,
342
+ },
343
+ };
344
+ }
345
+ function buildApproveBuilderFeeTypedData(nonce, isMainnet) {
346
+ return {
347
+ domain: HL_DOMAIN,
348
+ types: {
349
+ EIP712Domain: EIP712_DOMAIN_TYPE,
350
+ 'HyperliquidTransaction:ApproveBuilderFee': [
351
+ { name: 'hyperliquidChain', type: 'string' },
352
+ { name: 'maxFeeRate', type: 'string' },
353
+ { name: 'builder', type: 'address' },
354
+ { name: 'nonce', type: 'uint64' },
355
+ ],
356
+ },
357
+ primaryType: 'HyperliquidTransaction:ApproveBuilderFee',
358
+ message: {
359
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
360
+ maxFeeRate: BUILDER_FEE_RATE,
361
+ builder: BUILDER_ADDRESS,
362
+ nonce,
363
+ },
364
+ };
365
+ }
366
+ function buildWithdrawTypedData(destination, amount, nonce, isMainnet) {
367
+ return {
368
+ domain: HL_DOMAIN,
369
+ types: {
370
+ EIP712Domain: EIP712_DOMAIN_TYPE,
371
+ 'HyperliquidTransaction:Withdraw': [
372
+ { name: 'hyperliquidChain', type: 'string' },
373
+ { name: 'destination', type: 'string' },
374
+ { name: 'amount', type: 'string' },
375
+ { name: 'time', type: 'uint64' },
376
+ ],
377
+ },
378
+ primaryType: 'HyperliquidTransaction:Withdraw',
379
+ message: {
380
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
381
+ destination,
382
+ amount,
383
+ time: nonce,
384
+ },
385
+ };
386
+ }
387
+ function buildTransferTypedData(amount, toPerp, nonce, isMainnet) {
388
+ return {
389
+ domain: HL_DOMAIN,
390
+ types: {
391
+ EIP712Domain: EIP712_DOMAIN_TYPE,
392
+ 'HyperliquidTransaction:UsdClassTransfer': [
393
+ { name: 'hyperliquidChain', type: 'string' },
394
+ { name: 'amount', type: 'string' },
395
+ { name: 'toPerp', type: 'bool' },
396
+ { name: 'nonce', type: 'uint64' },
397
+ ],
398
+ },
399
+ primaryType: 'HyperliquidTransaction:UsdClassTransfer',
400
+ message: {
401
+ hyperliquidChain: isMainnet ? 'Mainnet' : 'Testnet',
402
+ amount,
403
+ toPerp,
404
+ nonce,
405
+ },
406
+ };
407
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@nexstone/rift-cli",
3
+ "version": "0.1.1",
4
+ "description": "RIFT — Research / Iteration / Forecast / Trade",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "bin": {
9
+ "rift": "./bin/run.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "bin"
14
+ ],
15
+ "dependencies": {
16
+ "@anthropic-ai/sdk": "^0.91.1",
17
+ "@modelcontextprotocol/sdk": "^1.29.0",
18
+ "@oclif/core": "^4",
19
+ "@oclif/plugin-help": "^6",
20
+ "@walletconnect/sign-client": "^2.23.9",
21
+ "@walletconnect/types": "^2.23.9",
22
+ "chalk": "^5",
23
+ "qrcode-terminal": "^0.12.0",
24
+ "viem": "^2",
25
+ "zod": "^3.25.76"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22",
29
+ "typescript": "^5.7"
30
+ },
31
+ "oclif": {
32
+ "bin": "rift",
33
+ "dirname": "rift",
34
+ "commands": "./dist/commands",
35
+ "default": "home",
36
+ "plugins": [
37
+ "@oclif/plugin-help"
38
+ ],
39
+ "topicSeparator": " "
40
+ },
41
+ "engines": {
42
+ "node": ">=20"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc",
46
+ "dev": "tsc --watch",
47
+ "lint": "tsc --noEmit"
48
+ }
49
+ }