minara 0.1.0 → 0.1.2
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.
- package/dist/api/auth.d.ts +1 -1
- package/dist/api/chat.d.ts +2 -2
- package/dist/api/client.js +6 -2
- package/dist/api/copytrade.d.ts +2 -2
- package/dist/api/crosschain.d.ts +10 -10
- package/dist/api/perps.d.ts +14 -14
- package/dist/api/tokens.d.ts +11 -10
- package/dist/api/tradeconfig.d.ts +2 -1
- package/dist/commands/account.js +4 -8
- package/dist/commands/assets.js +4 -8
- package/dist/commands/chat.js +23 -27
- package/dist/commands/config.js +3 -3
- package/dist/commands/copy-trade.js +23 -43
- package/dist/commands/deposit.js +7 -29
- package/dist/commands/discover.js +17 -29
- package/dist/commands/limit-order.js +15 -30
- package/dist/commands/login.js +36 -70
- package/dist/commands/logout.js +8 -4
- package/dist/commands/perps.js +53 -80
- package/dist/commands/swap.js +7 -22
- package/dist/commands/transfer.js +8 -24
- package/dist/commands/withdraw.js +17 -45
- package/dist/config.js +8 -3
- package/dist/index.js +2 -1
- package/dist/types.d.ts +72 -4
- package/dist/utils.d.ts +22 -0
- package/dist/utils.js +69 -0
- package/package.json +4 -1
package/dist/api/auth.d.ts
CHANGED
|
@@ -27,4 +27,4 @@ export declare function addFavoriteTokens(token: string, payload: FavoriteTokens
|
|
|
27
27
|
tokens: string[];
|
|
28
28
|
}>>;
|
|
29
29
|
/** Get invite history */
|
|
30
|
-
export declare function getInviteHistory(token: string): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
30
|
+
export declare function getInviteHistory(token: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
package/dist/api/chat.d.ts
CHANGED
|
@@ -14,6 +14,6 @@ export declare function updateChatName(token: string, chatId: string, name: stri
|
|
|
14
14
|
/** Delete chat */
|
|
15
15
|
export declare function deleteChat(token: string, chatId: string): Promise<import("../types.js").ApiResponse<void>>;
|
|
16
16
|
/** Search chats */
|
|
17
|
-
export declare function searchChats(token: string, query: string, limit?: number, offset?: number): Promise<import("../types.js").ApiResponse<
|
|
17
|
+
export declare function searchChats(token: string, query: string, limit?: number, offset?: number): Promise<import("../types.js").ApiResponse<ChatInfo[]>>;
|
|
18
18
|
/** Get available chat models */
|
|
19
|
-
export declare function getChatModels(token: string): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
19
|
+
export declare function getChatModels(token: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
package/dist/api/client.js
CHANGED
|
@@ -49,6 +49,7 @@ async function requestImpl(path, opts, isRetry) {
|
|
|
49
49
|
if (!res.ok) {
|
|
50
50
|
return { success: false, error: { code: res.status, message: text || res.statusText } };
|
|
51
51
|
}
|
|
52
|
+
// Non-JSON success response — wrap the text as data
|
|
52
53
|
return { success: true, data: text };
|
|
53
54
|
}
|
|
54
55
|
if (!res.ok) {
|
|
@@ -101,8 +102,11 @@ async function handleAuthExpired(path, opts) {
|
|
|
101
102
|
return requestImpl(path, { ...opts, token: newToken }, true);
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
|
-
catch {
|
|
105
|
-
// Module load failure or unexpected error — fall through
|
|
105
|
+
catch (err) {
|
|
106
|
+
// Module load failure or unexpected error — log for debugging, fall through
|
|
107
|
+
if (process.env.DEBUG) {
|
|
108
|
+
console.error('[minara] auth-refresh error:', err instanceof Error ? err.message : err);
|
|
109
|
+
}
|
|
106
110
|
}
|
|
107
111
|
return {
|
|
108
112
|
success: false,
|
package/dist/api/copytrade.d.ts
CHANGED
|
@@ -14,6 +14,6 @@ export declare function startCopyTrade(token: string, id: string): Promise<impor
|
|
|
14
14
|
/** Stop copy trade */
|
|
15
15
|
export declare function stopCopyTrade(token: string, id: string): Promise<import("../types.js").ApiResponse<void>>;
|
|
16
16
|
/** Get copy trade activity */
|
|
17
|
-
export declare function getCopyTradeActivity(token: string, id: string): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
17
|
+
export declare function getCopyTradeActivity(token: string, id: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
18
18
|
/** Get copy trade PnL chart */
|
|
19
|
-
export declare function getCopyTradePnl(token: string, id: string): Promise<import("../types.js").ApiResponse<unknown
|
|
19
|
+
export declare function getCopyTradePnl(token: string, id: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>>>;
|
package/dist/api/crosschain.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type { CrossChainSwapDto, CrossChainTransferDto, CrossChainActivitiesDto } from '../types.js';
|
|
1
|
+
import type { CrossChainSwapDto, CrossChainTransferDto, CrossChainActivitiesDto, CrossChainAccount, WalletAsset, TransactionResult } from '../types.js';
|
|
2
2
|
/** Get cross-chain account info */
|
|
3
|
-
export declare function getAccount(token: string): Promise<import("../types.js").ApiResponse<
|
|
3
|
+
export declare function getAccount(token: string): Promise<import("../types.js").ApiResponse<CrossChainAccount>>;
|
|
4
4
|
/** Get wallet assets */
|
|
5
|
-
export declare function getAssets(token: string): Promise<import("../types.js").ApiResponse<
|
|
5
|
+
export declare function getAssets(token: string): Promise<import("../types.js").ApiResponse<WalletAsset[]>>;
|
|
6
6
|
/** Execute a single swap */
|
|
7
|
-
export declare function swap(token: string, dto: CrossChainSwapDto): Promise<import("../types.js").ApiResponse<
|
|
7
|
+
export declare function swap(token: string, dto: CrossChainSwapDto): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
|
8
8
|
/** Execute multiple swaps */
|
|
9
|
-
export declare function swaps(token: string, swapList: CrossChainSwapDto[]): Promise<import("../types.js").ApiResponse<
|
|
9
|
+
export declare function swaps(token: string, swapList: CrossChainSwapDto[]): Promise<import("../types.js").ApiResponse<TransactionResult[]>>;
|
|
10
10
|
/** Simulate swaps (dry-run) */
|
|
11
|
-
export declare function swapsSimulate(token: string, swapList: CrossChainSwapDto[]): Promise<import("../types.js").ApiResponse<
|
|
11
|
+
export declare function swapsSimulate(token: string, swapList: CrossChainSwapDto[]): Promise<import("../types.js").ApiResponse<TransactionResult[]>>;
|
|
12
12
|
/** Transfer tokens */
|
|
13
|
-
export declare function transfer(token: string, dto: CrossChainTransferDto): Promise<import("../types.js").ApiResponse<
|
|
13
|
+
export declare function transfer(token: string, dto: CrossChainTransferDto): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
|
14
14
|
/** Get activities */
|
|
15
|
-
export declare function getActivities(token: string, dto: CrossChainActivitiesDto): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
15
|
+
export declare function getActivities(token: string, dto: CrossChainActivitiesDto): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
16
16
|
/** Get PnL history */
|
|
17
|
-
export declare function getPnlHistory(token: string, type: string): Promise<import("../types.js").ApiResponse<unknown
|
|
17
|
+
export declare function getPnlHistory(token: string, type: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>>>;
|
|
18
18
|
/** Check transaction statuses */
|
|
19
|
-
export declare function getStatuses(token: string, transactionIds: string[]): Promise<import("../types.js").ApiResponse<
|
|
19
|
+
export declare function getStatuses(token: string, transactionIds: string[]): Promise<import("../types.js").ApiResponse<TransactionResult[]>>;
|
package/dist/api/perps.d.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import type { PerpsDepositDto, PerpsWithdrawDto, PerpsPlaceOrdersDto, PerpsCancelOrdersDto, UpdateLeverageDto } from '../types.js';
|
|
1
|
+
import type { PerpsDepositDto, PerpsWithdrawDto, PerpsPlaceOrdersDto, PerpsCancelOrdersDto, UpdateLeverageDto, PerpsPosition, TokenPrice, TransactionResult } from '../types.js';
|
|
2
2
|
/** Deposit USDC to perps (min 5 USDC) */
|
|
3
|
-
export declare function deposit(token: string, dto: PerpsDepositDto): Promise<import("../types.js").ApiResponse<
|
|
3
|
+
export declare function deposit(token: string, dto: PerpsDepositDto): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
|
4
4
|
/** Withdraw USDC from perps */
|
|
5
|
-
export declare function withdraw(token: string, dto: PerpsWithdrawDto): Promise<import("../types.js").ApiResponse<
|
|
5
|
+
export declare function withdraw(token: string, dto: PerpsWithdrawDto): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
|
6
6
|
/** Place perp orders */
|
|
7
|
-
export declare function placeOrders(token: string, dto: PerpsPlaceOrdersDto): Promise<import("../types.js").ApiResponse<
|
|
7
|
+
export declare function placeOrders(token: string, dto: PerpsPlaceOrdersDto): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
|
8
8
|
/** Cancel perp orders */
|
|
9
|
-
export declare function cancelOrders(token: string, dto: PerpsCancelOrdersDto): Promise<import("../types.js").ApiResponse<
|
|
9
|
+
export declare function cancelOrders(token: string, dto: PerpsCancelOrdersDto): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
|
10
10
|
/** Modify existing orders */
|
|
11
|
-
export declare function modifyOrders(token: string, dto: PerpsCancelOrdersDto): Promise<import("../types.js").ApiResponse<
|
|
11
|
+
export declare function modifyOrders(token: string, dto: PerpsCancelOrdersDto): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
|
12
12
|
/** Update leverage */
|
|
13
|
-
export declare function updateLeverage(token: string, dto: UpdateLeverageDto): Promise<import("../types.js").ApiResponse<
|
|
13
|
+
export declare function updateLeverage(token: string, dto: UpdateLeverageDto): Promise<import("../types.js").ApiResponse<void>>;
|
|
14
14
|
/** Get all positions */
|
|
15
|
-
export declare function getPositions(token: string): Promise<import("../types.js").ApiResponse<
|
|
15
|
+
export declare function getPositions(token: string): Promise<import("../types.js").ApiResponse<PerpsPosition[]>>;
|
|
16
16
|
/** Get completed trades */
|
|
17
|
-
export declare function getCompletedTrades(token: string): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
17
|
+
export declare function getCompletedTrades(token: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
18
18
|
/** Get token prices */
|
|
19
|
-
export declare function getTokenPrices(token: string): Promise<import("../types.js").ApiResponse<
|
|
19
|
+
export declare function getTokenPrices(token: string): Promise<import("../types.js").ApiResponse<TokenPrice[]>>;
|
|
20
20
|
/** Get fund records */
|
|
21
|
-
export declare function getFundRecords(token: string, page: number, limit: number): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
21
|
+
export declare function getFundRecords(token: string, page: number, limit: number): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
22
22
|
/** Get equity history chart */
|
|
23
|
-
export declare function getEquityHistory(token: string): Promise<import("../types.js").ApiResponse<unknown
|
|
23
|
+
export declare function getEquityHistory(token: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>>>;
|
|
24
24
|
/** Get all decisions */
|
|
25
|
-
export declare function getDecisions(token: string): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
25
|
+
export declare function getDecisions(token: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
26
26
|
/** Claim rewards */
|
|
27
|
-
export declare function claimRewards(token: string): Promise<import("../types.js").ApiResponse<
|
|
27
|
+
export declare function claimRewards(token: string): Promise<import("../types.js").ApiResponse<TransactionResult>>;
|
package/dist/api/tokens.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
import type { TokenInfo } from '../types.js';
|
|
1
2
|
/** Get trending tokens */
|
|
2
|
-
export declare function getTrendingTokens(): Promise<import("../types.js").ApiResponse<
|
|
3
|
+
export declare function getTrendingTokens(): Promise<import("../types.js").ApiResponse<TokenInfo[]>>;
|
|
3
4
|
/** Search tokens by keyword */
|
|
4
|
-
export declare function searchTokens(keyword: string): Promise<import("../types.js").ApiResponse<
|
|
5
|
+
export declare function searchTokens(keyword: string): Promise<import("../types.js").ApiResponse<TokenInfo[]>>;
|
|
5
6
|
/** Get project info for a token */
|
|
6
|
-
export declare function getProjectInfo(symbol: string, address: string): Promise<import("../types.js").ApiResponse<unknown
|
|
7
|
+
export declare function getProjectInfo(symbol: string, address: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>>>;
|
|
7
8
|
/** Get trending stocks */
|
|
8
|
-
export declare function getTrendingStocks(): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
9
|
+
export declare function getTrendingStocks(): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
9
10
|
/** Search stocks */
|
|
10
|
-
export declare function searchStocks(keyword: string): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
11
|
+
export declare function searchStocks(keyword: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
11
12
|
/** Get stock info */
|
|
12
|
-
export declare function getStockInfo(symbol: string): Promise<import("../types.js").ApiResponse<unknown
|
|
13
|
+
export declare function getStockInfo(symbol: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>>>;
|
|
13
14
|
/** Discover tokens by risk preference */
|
|
14
|
-
export declare function discoverTokens(riskPreference: string): Promise<import("../types.js").ApiResponse<
|
|
15
|
+
export declare function discoverTokens(riskPreference: string): Promise<import("../types.js").ApiResponse<TokenInfo[]>>;
|
|
15
16
|
/** Get events */
|
|
16
|
-
export declare function getEvents(page: string, pageSize: string, version: string, language: string): Promise<import("../types.js").ApiResponse<unknown>>;
|
|
17
|
+
export declare function getEvents(page: string, pageSize: string, version: string, language: string): Promise<import("../types.js").ApiResponse<Record<string, unknown>[]>>;
|
|
17
18
|
/** Get fear & greed index */
|
|
18
|
-
export declare function getFearGreedIndex(): Promise<import("../types.js").ApiResponse<unknown
|
|
19
|
+
export declare function getFearGreedIndex(): Promise<import("../types.js").ApiResponse<Record<string, unknown>>>;
|
|
19
20
|
/** Get bitcoin metrics */
|
|
20
|
-
export declare function getBitcoinMetrics(): Promise<import("../types.js").ApiResponse<unknown
|
|
21
|
+
export declare function getBitcoinMetrics(): Promise<import("../types.js").ApiResponse<Record<string, unknown>>>;
|
|
@@ -5,5 +5,6 @@ export declare function getTradeConfig(token: string): Promise<import("../types.
|
|
|
5
5
|
export declare function upsertTradeConfig(token: string, config: UserTradeConfig): Promise<import("../types.js").ApiResponse<UserTradeConfig>>;
|
|
6
6
|
/** Delete trade config */
|
|
7
7
|
export declare function deleteTradeConfig(token: string): Promise<import("../types.js").ApiResponse<void>>;
|
|
8
|
+
import type { GasFeeInfo } from '../types.js';
|
|
8
9
|
/** Get gas fees */
|
|
9
|
-
export declare function getGasFees(token: string): Promise<import("../types.js").ApiResponse<
|
|
10
|
+
export declare function getGasFees(token: string): Promise<import("../types.js").ApiResponse<GasFeeInfo[]>>;
|
package/dist/commands/account.js
CHANGED
|
@@ -2,20 +2,16 @@ import { Command } from 'commander';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { getCurrentUser } from '../api/auth.js';
|
|
4
4
|
import { requireAuth } from '../config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { spinner, unwrapApi, wrapAction } from '../utils.js';
|
|
6
6
|
export const accountCommand = new Command('account')
|
|
7
7
|
.alias('me')
|
|
8
8
|
.description('View your Minara account info')
|
|
9
|
-
.action(async () => {
|
|
9
|
+
.action(wrapAction(async () => {
|
|
10
10
|
const creds = requireAuth();
|
|
11
11
|
const spin = spinner('Fetching account info…');
|
|
12
12
|
const res = await getCurrentUser(creds.accessToken);
|
|
13
13
|
spin.stop();
|
|
14
|
-
|
|
15
|
-
error(res.error?.message ?? 'Failed to fetch account info');
|
|
16
|
-
process.exit(1);
|
|
17
|
-
}
|
|
18
|
-
const u = res.data;
|
|
14
|
+
const u = unwrapApi(res, 'Failed to fetch account info');
|
|
19
15
|
console.log('');
|
|
20
16
|
console.log(chalk.bold('Account Info:'));
|
|
21
17
|
if (u.displayName)
|
|
@@ -41,4 +37,4 @@ export const accountCommand = new Command('account')
|
|
|
41
37
|
}
|
|
42
38
|
}
|
|
43
39
|
console.log('');
|
|
44
|
-
});
|
|
40
|
+
}));
|
package/dist/commands/assets.js
CHANGED
|
@@ -2,19 +2,15 @@ import { Command } from 'commander';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { getAssets } from '../api/crosschain.js';
|
|
4
4
|
import { requireAuth } from '../config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { spinner, unwrapApi, wrapAction } from '../utils.js';
|
|
6
6
|
export const assetsCommand = new Command('assets')
|
|
7
7
|
.description('View your wallet assets across chains')
|
|
8
|
-
.action(async () => {
|
|
8
|
+
.action(wrapAction(async () => {
|
|
9
9
|
const creds = requireAuth();
|
|
10
10
|
const spin = spinner('Fetching assets…');
|
|
11
11
|
const res = await getAssets(creds.accessToken);
|
|
12
12
|
spin.stop();
|
|
13
|
-
|
|
14
|
-
error(res.error?.message ?? 'Failed to fetch assets');
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
17
|
-
const data = res.data;
|
|
13
|
+
const data = unwrapApi(res, 'Failed to fetch assets');
|
|
18
14
|
if (Array.isArray(data) && data.length === 0) {
|
|
19
15
|
console.log(chalk.dim('No assets found.'));
|
|
20
16
|
return;
|
|
@@ -23,4 +19,4 @@ export const assetsCommand = new Command('assets')
|
|
|
23
19
|
console.log(chalk.bold('Your Assets:'));
|
|
24
20
|
console.log(JSON.stringify(data, null, 2));
|
|
25
21
|
console.log('');
|
|
26
|
-
});
|
|
22
|
+
}));
|
package/dist/commands/chat.js
CHANGED
|
@@ -3,7 +3,7 @@ import { select } from '@inquirer/prompts';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { sendChatStream, listChats, getMemories } from '../api/chat.js';
|
|
5
5
|
import { requireAuth } from '../config.js';
|
|
6
|
-
import { error, info, spinner } from '../utils.js';
|
|
6
|
+
import { error, info, spinner, unwrapApi, wrapAction } from '../utils.js';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
8
8
|
import { randomUUID } from 'node:crypto';
|
|
9
9
|
/** Parse SSE stream and yield text chunks */
|
|
@@ -13,21 +13,22 @@ async function* parseSSE(response) {
|
|
|
13
13
|
return;
|
|
14
14
|
const decoder = new TextDecoder();
|
|
15
15
|
let buffer = '';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
try {
|
|
17
|
+
while (true) {
|
|
18
|
+
const { done, value } = await reader.read();
|
|
19
|
+
if (done)
|
|
20
|
+
break;
|
|
21
|
+
buffer += decoder.decode(value, { stream: true });
|
|
22
|
+
const lines = buffer.split('\n');
|
|
23
|
+
buffer = lines.pop() ?? '';
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
if (!line.startsWith('data:'))
|
|
26
|
+
continue;
|
|
25
27
|
const data = line.slice(5).trim();
|
|
26
28
|
if (data === '[DONE]')
|
|
27
29
|
return;
|
|
28
30
|
try {
|
|
29
31
|
const parsed = JSON.parse(data);
|
|
30
|
-
// Extract text content from various SSE event formats
|
|
31
32
|
const text = parsed?.choices?.[0]?.delta?.content
|
|
32
33
|
?? parsed?.content
|
|
33
34
|
?? parsed?.text
|
|
@@ -38,12 +39,15 @@ async function* parseSSE(response) {
|
|
|
38
39
|
}
|
|
39
40
|
catch {
|
|
40
41
|
// Non-JSON data line — might be raw text
|
|
41
|
-
if (data
|
|
42
|
+
if (data)
|
|
42
43
|
yield data;
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
}
|
|
48
|
+
finally {
|
|
49
|
+
reader.releaseLock();
|
|
50
|
+
}
|
|
47
51
|
}
|
|
48
52
|
export const chatCommand = new Command('chat')
|
|
49
53
|
.description('Chat with Minara AI assistant')
|
|
@@ -53,24 +57,20 @@ export const chatCommand = new Command('chat')
|
|
|
53
57
|
.option('--history <chatId>', 'Show chat history')
|
|
54
58
|
.option('--thinking', 'Enable thinking/degen mode')
|
|
55
59
|
.option('--deep-research', 'Enable deep research mode')
|
|
56
|
-
.action(async (messageArg, opts) => {
|
|
60
|
+
.action(wrapAction(async (messageArg, opts) => {
|
|
57
61
|
const creds = requireAuth();
|
|
58
62
|
// ── List chats ───────────────────────────────────────────────────────
|
|
59
63
|
if (opts?.list) {
|
|
60
64
|
const spin = spinner('Fetching chats…');
|
|
61
65
|
const res = await listChats(creds.accessToken);
|
|
62
66
|
spin.stop();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
const chats = res.data;
|
|
68
|
-
if (!chats || chats.length === 0) {
|
|
67
|
+
const chats = unwrapApi(res, 'Failed to fetch chats');
|
|
68
|
+
if (chats.length === 0) {
|
|
69
69
|
console.log(chalk.dim('No chats yet.'));
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
for (const c of chats) {
|
|
73
|
-
console.log(` ${chalk.bold((c.chatId
|
|
73
|
+
console.log(` ${chalk.bold((c.chatId).slice(0, 12))}… ${c.name ?? '(untitled)'} ${chalk.dim(c.updatedAt ?? '')}`);
|
|
74
74
|
}
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
@@ -79,11 +79,7 @@ export const chatCommand = new Command('chat')
|
|
|
79
79
|
const spin = spinner('Loading history…');
|
|
80
80
|
const res = await getMemories(creds.accessToken, opts.history);
|
|
81
81
|
spin.stop();
|
|
82
|
-
|
|
83
|
-
error(res.error?.message ?? 'Failed');
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
const memories = res.data;
|
|
82
|
+
const memories = unwrapApi(res, 'Failed to load chat history');
|
|
87
83
|
for (const m of memories) {
|
|
88
84
|
const prefix = m.role === 'user' ? chalk.blue.bold('You ') : chalk.green.bold('Minara');
|
|
89
85
|
const content = typeof m.content === 'string' ? m.content : JSON.stringify(m.content);
|
|
@@ -110,7 +106,7 @@ export const chatCommand = new Command('chat')
|
|
|
110
106
|
chatId = await select({
|
|
111
107
|
message: 'Select chat:',
|
|
112
108
|
choices: chats.map((c) => ({
|
|
113
|
-
name: `${(c.chatId
|
|
109
|
+
name: `${(c.chatId).slice(0, 12)}… ${c.name ?? '(untitled)'}`,
|
|
114
110
|
value: c.chatId,
|
|
115
111
|
})),
|
|
116
112
|
});
|
|
@@ -181,4 +177,4 @@ export const chatCommand = new Command('chat')
|
|
|
181
177
|
}
|
|
182
178
|
await sendAndPrint(userMsg);
|
|
183
179
|
}
|
|
184
|
-
});
|
|
180
|
+
}));
|
package/dist/commands/config.js
CHANGED
|
@@ -2,10 +2,10 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { input, select } from '@inquirer/prompts';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { loadConfig, saveConfig, getMinaraDir } from '../config.js';
|
|
5
|
-
import { success, info } from '../utils.js';
|
|
5
|
+
import { success, info, wrapAction } from '../utils.js';
|
|
6
6
|
export const configCommand = new Command('config')
|
|
7
7
|
.description('View or update CLI configuration')
|
|
8
|
-
.action(async () => {
|
|
8
|
+
.action(wrapAction(async () => {
|
|
9
9
|
const action = await select({
|
|
10
10
|
message: 'Configuration:',
|
|
11
11
|
choices: [
|
|
@@ -45,4 +45,4 @@ export const configCommand = new Command('config')
|
|
|
45
45
|
info(`Config directory: ${getMinaraDir()}`);
|
|
46
46
|
break;
|
|
47
47
|
}
|
|
48
|
-
});
|
|
48
|
+
}));
|
|
@@ -3,25 +3,20 @@ import { input, select, confirm, number as numberPrompt } from '@inquirer/prompt
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import * as ctApi from '../api/copytrade.js';
|
|
5
5
|
import { requireAuth } from '../config.js';
|
|
6
|
-
import { success,
|
|
7
|
-
import { SUPPORTED_CHAINS } from '../types.js';
|
|
6
|
+
import { success, info, spinner, assertApiOk, selectChain, wrapAction } from '../utils.js';
|
|
8
7
|
// ─── create ──────────────────────────────────────────────────────────────
|
|
9
8
|
const createCmd = new Command('create')
|
|
10
9
|
.description('Create a copy trade bot')
|
|
11
10
|
.option('-y, --yes', 'Skip confirmation')
|
|
12
|
-
.action(async (opts) => {
|
|
11
|
+
.action(wrapAction(async (opts) => {
|
|
13
12
|
const creds = requireAuth();
|
|
14
|
-
const chain = await
|
|
15
|
-
message: 'Chain:',
|
|
16
|
-
choices: SUPPORTED_CHAINS.map((c) => ({ name: c, value: c })),
|
|
17
|
-
default: 'solana',
|
|
18
|
-
});
|
|
13
|
+
const chain = await selectChain('Chain:', true);
|
|
19
14
|
const targetAddress = await input({
|
|
20
15
|
message: 'Target wallet address to copy:',
|
|
21
16
|
validate: (v) => (v.length > 5 ? true : 'Enter a valid address'),
|
|
22
17
|
});
|
|
23
18
|
const name = await input({ message: 'Name for this copy trade (optional):' }) || undefined;
|
|
24
|
-
const fixedAmount = await numberPrompt({ message: 'Fixed buy amount (USD) per copy:', min: 1 });
|
|
19
|
+
const fixedAmount = await numberPrompt({ message: 'Fixed buy amount (USD) per copy:', min: 1, required: true });
|
|
25
20
|
const copySell = await confirm({ message: 'Also copy sell actions?', default: true });
|
|
26
21
|
let copySellSamePercentage = false;
|
|
27
22
|
let copySellQuitPercentage;
|
|
@@ -57,40 +52,34 @@ const createCmd = new Command('create')
|
|
|
57
52
|
const res = await ctApi.createCopyTrade(creds.accessToken, {
|
|
58
53
|
chain, targetAddress, name,
|
|
59
54
|
mode: 'fixedAmount',
|
|
60
|
-
fixedAmount: fixedAmount
|
|
55
|
+
fixedAmount: fixedAmount,
|
|
61
56
|
copySell,
|
|
62
57
|
copySellSamePercentage,
|
|
63
58
|
copySellQuitPercentage,
|
|
64
59
|
});
|
|
65
60
|
spin.stop();
|
|
66
|
-
|
|
67
|
-
error(res.error?.message ?? 'Failed');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
61
|
+
assertApiOk(res, 'Failed to create copy trade');
|
|
70
62
|
success('Copy trade created!');
|
|
71
63
|
if (res.data)
|
|
72
64
|
console.log(JSON.stringify(res.data, null, 2));
|
|
73
|
-
});
|
|
65
|
+
}));
|
|
74
66
|
// ─── list ────────────────────────────────────────────────────────────────
|
|
75
67
|
const listCmd = new Command('list')
|
|
76
68
|
.alias('ls')
|
|
77
69
|
.description('List your copy trades')
|
|
78
|
-
.action(async () => {
|
|
70
|
+
.action(wrapAction(async () => {
|
|
79
71
|
const creds = requireAuth();
|
|
80
72
|
const spin = spinner('Fetching copy trades…');
|
|
81
73
|
const res = await ctApi.listCopyTrades(creds.accessToken);
|
|
82
74
|
spin.stop();
|
|
83
|
-
|
|
84
|
-
error(res.error?.message ?? 'Failed');
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
75
|
+
assertApiOk(res, 'Failed to fetch copy trades');
|
|
87
76
|
const data = res.data;
|
|
88
|
-
if (!data ||
|
|
77
|
+
if (!data || data.length === 0) {
|
|
89
78
|
console.log(chalk.dim('No copy trades.'));
|
|
90
79
|
return;
|
|
91
80
|
}
|
|
92
81
|
console.log(JSON.stringify(data, null, 2));
|
|
93
|
-
});
|
|
82
|
+
}));
|
|
94
83
|
// ─── start / stop ────────────────────────────────────────────────────────
|
|
95
84
|
async function pickCopyTrade(token) {
|
|
96
85
|
const spin = spinner('Fetching copy trades…');
|
|
@@ -104,7 +93,7 @@ async function pickCopyTrade(token) {
|
|
|
104
93
|
return select({
|
|
105
94
|
message: 'Select copy trade:',
|
|
106
95
|
choices: trades.map((t) => ({
|
|
107
|
-
name: `[${t.id
|
|
96
|
+
name: `[${t.id.slice(0, 12)}…] ${t.name ?? t.targetAddress} status=${t.status ?? '?'}`,
|
|
108
97
|
value: t.id,
|
|
109
98
|
})),
|
|
110
99
|
});
|
|
@@ -112,22 +101,19 @@ async function pickCopyTrade(token) {
|
|
|
112
101
|
const startCmd = new Command('start')
|
|
113
102
|
.description('Start (resume) a copy trade')
|
|
114
103
|
.argument('[id]', 'Copy trade ID')
|
|
115
|
-
.action(async (idArg) => {
|
|
104
|
+
.action(wrapAction(async (idArg) => {
|
|
116
105
|
const creds = requireAuth();
|
|
117
106
|
const id = idArg ?? await pickCopyTrade(creds.accessToken);
|
|
118
107
|
const spin = spinner('Starting…');
|
|
119
108
|
const res = await ctApi.startCopyTrade(creds.accessToken, id);
|
|
120
109
|
spin.stop();
|
|
121
|
-
|
|
122
|
-
error(res.error?.message ?? 'Failed');
|
|
123
|
-
process.exit(1);
|
|
124
|
-
}
|
|
110
|
+
assertApiOk(res, 'Failed to start copy trade');
|
|
125
111
|
success('Copy trade started.');
|
|
126
|
-
});
|
|
112
|
+
}));
|
|
127
113
|
const stopCmd = new Command('stop')
|
|
128
114
|
.description('Stop (pause) a copy trade')
|
|
129
115
|
.argument('[id]', 'Copy trade ID')
|
|
130
|
-
.action(async (idArg) => {
|
|
116
|
+
.action(wrapAction(async (idArg) => {
|
|
131
117
|
const creds = requireAuth();
|
|
132
118
|
const id = idArg ?? await pickCopyTrade(creds.accessToken);
|
|
133
119
|
const ok = await confirm({ message: `Stop copy trade ${id.slice(0, 12)}…?`, default: false });
|
|
@@ -136,18 +122,15 @@ const stopCmd = new Command('stop')
|
|
|
136
122
|
const spin = spinner('Stopping…');
|
|
137
123
|
const res = await ctApi.stopCopyTrade(creds.accessToken, id);
|
|
138
124
|
spin.stop();
|
|
139
|
-
|
|
140
|
-
error(res.error?.message ?? 'Failed');
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
125
|
+
assertApiOk(res, 'Failed to stop copy trade');
|
|
143
126
|
success('Copy trade stopped.');
|
|
144
|
-
});
|
|
127
|
+
}));
|
|
145
128
|
// ─── delete ──────────────────────────────────────────────────────────────
|
|
146
129
|
const deleteCmd = new Command('delete')
|
|
147
130
|
.description('Delete a copy trade')
|
|
148
131
|
.argument('[id]', 'Copy trade ID')
|
|
149
132
|
.option('-y, --yes', 'Skip confirmation')
|
|
150
|
-
.action(async (idArg, opts) => {
|
|
133
|
+
.action(wrapAction(async (idArg, opts) => {
|
|
151
134
|
const creds = requireAuth();
|
|
152
135
|
const id = idArg ?? await pickCopyTrade(creds.accessToken);
|
|
153
136
|
if (!opts?.yes) {
|
|
@@ -158,12 +141,9 @@ const deleteCmd = new Command('delete')
|
|
|
158
141
|
const spin = spinner('Deleting…');
|
|
159
142
|
const res = await ctApi.deleteCopyTrade(creds.accessToken, id);
|
|
160
143
|
spin.stop();
|
|
161
|
-
|
|
162
|
-
error(res.error?.message ?? 'Failed');
|
|
163
|
-
process.exit(1);
|
|
164
|
-
}
|
|
144
|
+
assertApiOk(res, 'Failed to delete copy trade');
|
|
165
145
|
success('Copy trade deleted.');
|
|
166
|
-
});
|
|
146
|
+
}));
|
|
167
147
|
// ─── parent ──────────────────────────────────────────────────────────────
|
|
168
148
|
export const copyTradeCommand = new Command('copy-trade')
|
|
169
149
|
.alias('ct')
|
|
@@ -173,7 +153,7 @@ export const copyTradeCommand = new Command('copy-trade')
|
|
|
173
153
|
.addCommand(startCmd)
|
|
174
154
|
.addCommand(stopCmd)
|
|
175
155
|
.addCommand(deleteCmd)
|
|
176
|
-
.action(async () => {
|
|
156
|
+
.action(wrapAction(async () => {
|
|
177
157
|
const action = await select({
|
|
178
158
|
message: 'Copy Trade:',
|
|
179
159
|
choices: [
|
|
@@ -187,4 +167,4 @@ export const copyTradeCommand = new Command('copy-trade')
|
|
|
187
167
|
const sub = copyTradeCommand.commands.find((c) => c.name() === action);
|
|
188
168
|
if (sub)
|
|
189
169
|
await sub.parseAsync([], { from: 'user' });
|
|
190
|
-
});
|
|
170
|
+
}));
|
package/dist/commands/deposit.js
CHANGED
|
@@ -5,11 +5,9 @@ import Table from 'cli-table3';
|
|
|
5
5
|
import { getCurrentUser } from '../api/auth.js';
|
|
6
6
|
import { getAccount } from '../api/crosschain.js';
|
|
7
7
|
import { requireAuth } from '../config.js';
|
|
8
|
-
import {
|
|
8
|
+
import { info, spinner, unwrapApi, wrapAction } from '../utils.js';
|
|
9
9
|
/**
|
|
10
10
|
* Map wallet type keys from /auth/me → human-readable chain info.
|
|
11
|
-
* Minara custodial wallets follow naming like:
|
|
12
|
-
* spot-evm, abstraction-solana, spot-solana, etc.
|
|
13
11
|
*/
|
|
14
12
|
function describeWalletType(key) {
|
|
15
13
|
const lower = key.toLowerCase();
|
|
@@ -20,47 +18,33 @@ function describeWalletType(key) {
|
|
|
20
18
|
};
|
|
21
19
|
}
|
|
22
20
|
if (lower.includes('solana')) {
|
|
23
|
-
return {
|
|
24
|
-
network: 'Solana',
|
|
25
|
-
chains: ['Solana'],
|
|
26
|
-
};
|
|
21
|
+
return { network: 'Solana', chains: ['Solana'] };
|
|
27
22
|
}
|
|
28
|
-
// Fallback
|
|
29
23
|
return { network: key, chains: [key] };
|
|
30
24
|
}
|
|
31
25
|
export const depositCommand = new Command('deposit')
|
|
32
26
|
.description('Show your deposit addresses and supported networks')
|
|
33
|
-
.action(async () => {
|
|
27
|
+
.action(wrapAction(async () => {
|
|
34
28
|
const creds = requireAuth();
|
|
35
|
-
// ── Fetch user wallets ───────────────────────────────────────────────
|
|
36
29
|
const spin = spinner('Fetching deposit addresses…');
|
|
37
30
|
const [userRes, accountRes] = await Promise.all([
|
|
38
31
|
getCurrentUser(creds.accessToken),
|
|
39
32
|
getAccount(creds.accessToken),
|
|
40
33
|
]);
|
|
41
34
|
spin.stop();
|
|
42
|
-
|
|
43
|
-
error(userRes.error?.message ?? 'Failed to fetch account info');
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
const user = userRes.data;
|
|
35
|
+
const user = unwrapApi(userRes, 'Failed to fetch account info');
|
|
47
36
|
const wallets = user.wallets;
|
|
48
37
|
if (!wallets || Object.keys(wallets).length === 0) {
|
|
49
38
|
info('No wallet addresses found. Your account may not have been fully initialized.');
|
|
50
39
|
info('Try logging in at https://minara.ai first, then run this command again.');
|
|
51
40
|
return;
|
|
52
41
|
}
|
|
53
|
-
// ── Display deposit addresses ────────────────────────────────────────
|
|
54
42
|
console.log('');
|
|
55
43
|
console.log(chalk.bold('Deposit Addresses'));
|
|
56
44
|
console.log(chalk.dim('Send tokens to the addresses below. Make sure to use the correct network!'));
|
|
57
45
|
console.log('');
|
|
58
46
|
const table = new Table({
|
|
59
|
-
head: [
|
|
60
|
-
chalk.white('Network'),
|
|
61
|
-
chalk.white('Address'),
|
|
62
|
-
chalk.white('Supported Chains'),
|
|
63
|
-
],
|
|
47
|
+
head: [chalk.white('Network'), chalk.white('Address'), chalk.white('Supported Chains')],
|
|
64
48
|
colWidths: [14, 48, 40],
|
|
65
49
|
wordWrap: true,
|
|
66
50
|
});
|
|
@@ -70,21 +54,15 @@ export const depositCommand = new Command('deposit')
|
|
|
70
54
|
continue;
|
|
71
55
|
seen.add(address);
|
|
72
56
|
const { network, chains } = describeWalletType(walletType);
|
|
73
|
-
table.push([
|
|
74
|
-
chalk.cyan.bold(network),
|
|
75
|
-
chalk.yellow(address),
|
|
76
|
-
chains.join(', '),
|
|
77
|
-
]);
|
|
57
|
+
table.push([chalk.cyan.bold(network), chalk.yellow(address), chains.join(', ')]);
|
|
78
58
|
}
|
|
79
59
|
console.log(table.toString());
|
|
80
|
-
// ── Warnings ─────────────────────────────────────────────────────────
|
|
81
60
|
console.log('');
|
|
82
61
|
console.log(chalk.red.bold('Important:'));
|
|
83
62
|
console.log(chalk.red(' • Only send tokens on the supported chains listed above.'));
|
|
84
63
|
console.log(chalk.red(' • Sending tokens on the wrong network may result in permanent loss.'));
|
|
85
64
|
console.log(chalk.red(' • EVM address supports all EVM-compatible chains (Ethereum, Base, Arbitrum, etc.)'));
|
|
86
65
|
console.log('');
|
|
87
|
-
// ── Also show cross-chain account details if available ───────────────
|
|
88
66
|
if (accountRes.success && accountRes.data) {
|
|
89
67
|
const wantDetails = await select({
|
|
90
68
|
message: 'Would you like to see detailed account info?',
|
|
@@ -98,4 +76,4 @@ export const depositCommand = new Command('deposit')
|
|
|
98
76
|
console.log(JSON.stringify(accountRes.data, null, 2));
|
|
99
77
|
}
|
|
100
78
|
}
|
|
101
|
-
});
|
|
79
|
+
}));
|