solana-tui-explorer 1.0.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.
- package/api.js +1786 -0
- package/bin/st.js +3 -0
- package/config.js +87 -0
- package/data.js +197 -0
- package/index.js +61 -0
- package/package.json +51 -0
- package/panels/dashboard.js +2199 -0
- package/panels/token.js +53 -0
- package/panels/wallet.js +55 -0
package/bin/st.js
ADDED
package/config.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// =============================================
|
|
2
|
+
// SOLANA TUI EXPLORER CLI — Config
|
|
3
|
+
// =============================================
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
// Solana Public RPC — override via SOLANA_RPC in .env for better reliability
|
|
7
|
+
SOLANA_RPC: process.env.SOLANA_RPC || 'https://api.mainnet-beta.solana.com',
|
|
8
|
+
|
|
9
|
+
// High-capacity public node for heavy Explorer queries
|
|
10
|
+
EXPLORER_RPC: 'https://solana-rpc.publicnode.com',
|
|
11
|
+
|
|
12
|
+
// DexScreener (Solana token prices — free, no key)
|
|
13
|
+
DEXSCREENER_BASE: 'https://api.dexscreener.com',
|
|
14
|
+
|
|
15
|
+
// CoinDesk Data API (major crypto prices — free tier works without key)
|
|
16
|
+
// Set COINDESK_API_KEY env var when you have one for higher rate limits.
|
|
17
|
+
COINDESK_BASE: 'https://data-api.coindesk.com',
|
|
18
|
+
COINDESK_MARKET: process.env.COINDESK_MARKET || 'coinbase',
|
|
19
|
+
COINDESK_API_KEY: process.env.COINDESK_API_KEY || '',
|
|
20
|
+
BIRDEYE_API_KEY: process.env.BIRDEYE_API_KEY || '',
|
|
21
|
+
RUGCHECK_API_KEY: process.env.RUGCHECK_API_KEY || '',
|
|
22
|
+
WHALE_ALERT_API_KEY: process.env.WHALE_ALERT_API_KEY || '',
|
|
23
|
+
BITQUERY_API_KEY: process.env.BITQUERY_API_KEY || '',
|
|
24
|
+
CRYPTOPANIC_API_KEY: process.env.CRYPTOPANIC_API_KEY || '',
|
|
25
|
+
COINMARKETCAP_API_KEY: process.env.COINMARKETCAP_API_KEY || '',
|
|
26
|
+
|
|
27
|
+
// SECURE BACKEND PROXY
|
|
28
|
+
// Routes traffic through our AWS EC2 instance instead of exposing keys to clients
|
|
29
|
+
PROXY_URL: process.env.PROXY_URL || 'http://100.26.192.172:3000',
|
|
30
|
+
|
|
31
|
+
AI_MODEL: 'llama-3.3-70b-versatile',
|
|
32
|
+
AI_SYSTEM_PROMPT: 'You are the Antigravity Solana Developer TUI AI. You act as an expert Solana systems developer, smart contract compiler, and transaction debugger. Help developers diagnose RPC simulation failures, decode hexadecimal transaction instruction error codes, explain Anchor constraints, and optimize compute units. Your responses must be concise, technical, and formatted for a terminal (no markdown headers, use plain text with accents).',
|
|
33
|
+
FAIRSCALE_API_KEY: process.env.FAIRSCALE_API_KEY || '',
|
|
34
|
+
|
|
35
|
+
// Major cryptos — fetched from CoinDesk (accurate spot prices in USD)
|
|
36
|
+
COINDESK_SYMBOLS: ['BTC', 'ETH', 'SOL'],
|
|
37
|
+
|
|
38
|
+
// Solana-native tokens — fetched from DexScreener
|
|
39
|
+
DEX_SYMBOLS: ['BONK','WIF','JUP','PYTH','RAY','ORCA','DRIFT','RENDER','POPCAT','FARTCOIN','TRUMP'],
|
|
40
|
+
|
|
41
|
+
// Combined display order (CoinDesk first, then DEX tokens)
|
|
42
|
+
MARKET_SYMBOLS: ['SOL','BTC','ETH','BONK','WIF','JUP','PYTH','RAY','ORCA','DRIFT','RENDER','POPCAT','FARTCOIN','TRUMP'],
|
|
43
|
+
|
|
44
|
+
// ── Token mint addresses on Solana (for DexScreener) ───────────
|
|
45
|
+
TOKEN_MINTS: {
|
|
46
|
+
SOL: 'So11111111111111111111111111111111111111112',
|
|
47
|
+
BTC: '9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E', // Portal wBTC
|
|
48
|
+
ETH: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs', // Portal wETH
|
|
49
|
+
BONK: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263',
|
|
50
|
+
WIF: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm',
|
|
51
|
+
JUP: 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN',
|
|
52
|
+
PYTH: 'HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3',
|
|
53
|
+
RAY: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R',
|
|
54
|
+
ORCA: 'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE',
|
|
55
|
+
DRIFT: 'DriFtupJYLTosbwoN8koMbEYSx54aFAVLddWsbksjwg7',
|
|
56
|
+
RENDER: 'rndrizKT3MK1iimdxRdWabcF7Zg7AR5T4nud4EkHBof',
|
|
57
|
+
POPCAT: '7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr',
|
|
58
|
+
FARTCOIN: '9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump',
|
|
59
|
+
TRUMP: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN',
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
TOKEN_NAMES: {
|
|
63
|
+
SOL: 'Solana',
|
|
64
|
+
BTC: 'Bitcoin',
|
|
65
|
+
ETH: 'Ethereum',
|
|
66
|
+
BONK: 'Bonk',
|
|
67
|
+
WIF: 'dogwifhat',
|
|
68
|
+
JUP: 'Jupiter',
|
|
69
|
+
PYTH: 'Pyth Network',
|
|
70
|
+
RAY: 'Raydium',
|
|
71
|
+
ORCA: 'Orca',
|
|
72
|
+
DRIFT: 'Drift Protocol',
|
|
73
|
+
RENDER: 'Render',
|
|
74
|
+
POPCAT: 'Popcat',
|
|
75
|
+
FARTCOIN: 'Fartcoin',
|
|
76
|
+
TRUMP: 'Official Trump',
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
// Refresh intervals (ms)
|
|
80
|
+
MARKET_REFRESH_MS: 30000,
|
|
81
|
+
NETWORK_REFRESH_MS: 30000,
|
|
82
|
+
TOKEN_REFRESH_MS: 30000,
|
|
83
|
+
WALLET_REFRESH_MS: 60000,
|
|
84
|
+
|
|
85
|
+
// Local testing session path
|
|
86
|
+
LITESVM_SESSION_PATH: process.env.LITESVM_SESSION_PATH || 'litesvm-session.json',
|
|
87
|
+
};
|
package/data.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// =============================================
|
|
2
|
+
// SOLANA TUI EXPLORER CLI — Live Data Store
|
|
3
|
+
// This module holds the current live state.
|
|
4
|
+
// dashboard.js calls loadMarketData(), loadNetworkData(), etc.
|
|
5
|
+
// Each returns the updated store or throws on failure.
|
|
6
|
+
// =============================================
|
|
7
|
+
|
|
8
|
+
const API = require('./api');
|
|
9
|
+
const CFG = require('./config');
|
|
10
|
+
const { fetchNewsAggregated } = API;
|
|
11
|
+
|
|
12
|
+
// ── Live data store ────────────────────────────────────
|
|
13
|
+
const DATA = {
|
|
14
|
+
// Populated by loadMarketData()
|
|
15
|
+
market: [],
|
|
16
|
+
topGainers: [],
|
|
17
|
+
topLosers: [],
|
|
18
|
+
sparklines: {},
|
|
19
|
+
chartData: { x: [], y: [] },
|
|
20
|
+
priceExchanges: [], // not available from DexScreener — show empty
|
|
21
|
+
|
|
22
|
+
// Populated by loadNetworkData()
|
|
23
|
+
networkStats: null,
|
|
24
|
+
|
|
25
|
+
// Populated on demand by loadWalletData(address)
|
|
26
|
+
wallet: null,
|
|
27
|
+
|
|
28
|
+
// Populated on demand by loadTokenData(mintOrSymbol)
|
|
29
|
+
token: null,
|
|
30
|
+
|
|
31
|
+
// Static/dummy — live feed is simulated from on-chain data
|
|
32
|
+
liveFeed: [
|
|
33
|
+
{ type: 'SWAP', text: 'SWAP 10,420,000 BONK → 243.8 SOL via Jupiter [4kXm...9nQr]' },
|
|
34
|
+
{ type: 'BUY', text: 'BUY 2,400 WIF ($6,888) on Raydium [7pLn...2wKs]' },
|
|
35
|
+
{ type: 'WHALE', text: 'WHALE 50,000 SOL moved from Binance [2rMk...8vPt]' },
|
|
36
|
+
{ type: 'SWAP', text: 'SWAP 84,200 USDC → 590 SOL via Orca [9sNp...5hJu]' },
|
|
37
|
+
{ type: 'ALERT', text: 'VOL SPIKE BONK +5% in 45min — unusual activity' },
|
|
38
|
+
{ type: 'BUY', text: 'BUY 120,000,000 BONK ($2,809) large wallet [6tQr...1dCv]' },
|
|
39
|
+
{ type: 'SWAP', text: 'SWAP 500 JUP → 402 USDC via Jupiter [3mNk...7rQs]' },
|
|
40
|
+
{ type: 'WHALE', text: 'WHALE 15,000 SOL staked new validator [8vLq...1uRp]' },
|
|
41
|
+
],
|
|
42
|
+
|
|
43
|
+
// Explorer Tab state
|
|
44
|
+
explorer: {
|
|
45
|
+
list: [],
|
|
46
|
+
details: null,
|
|
47
|
+
loading: false,
|
|
48
|
+
error: null
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// Alerts are static (no free alert API available)
|
|
52
|
+
alerts: [
|
|
53
|
+
{ id: 'ALT001', token: 'SOL', condition: 'PRICE > $150', status: 'ACTIVE', triggered: false, created: '04-14 09:00', triggeredAt: null },
|
|
54
|
+
{ id: 'ALT002', token: 'BONK', condition: 'VOL SPIKE > 50%/1h', status: 'TRIGGERED', triggered: true, created: '04-14 10:30', triggeredAt: '22:18:03' },
|
|
55
|
+
{ id: 'ALT003', token: 'WIF', condition: 'PRICE > $3.00', status: 'ACTIVE', triggered: false, created: '04-14 11:15', triggeredAt: null },
|
|
56
|
+
{ id: 'ALT004', token: 'ANY', condition: 'WHALE > $500K move', status: 'TRIGGERED', triggered: true, created: '04-14 08:00', triggeredAt: '21:47:22' },
|
|
57
|
+
{ id: 'ALT005', token: 'JUP', condition: 'PRICE < $1.00', status: 'ACTIVE', triggered: false, created: '04-13 18:00', triggeredAt: null },
|
|
58
|
+
],
|
|
59
|
+
|
|
60
|
+
// Populated by loadNewsData() — live aggregated news
|
|
61
|
+
news: [],
|
|
62
|
+
newsLastUpdated: null,
|
|
63
|
+
newsLoading: false,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// ═════════════════════════════════════════════════════════
|
|
67
|
+
// LOAD FUNCTIONS — called by dashboard.js
|
|
68
|
+
// ═════════════════════════════════════════════════════════
|
|
69
|
+
|
|
70
|
+
async function loadMarketData() {
|
|
71
|
+
const [result, macro] = await Promise.all([
|
|
72
|
+
API.fetchMarketData(),
|
|
73
|
+
API.fetchCMCMacroData()
|
|
74
|
+
]);
|
|
75
|
+
DATA.market = result.market;
|
|
76
|
+
DATA.topGainers = result.topGainers;
|
|
77
|
+
DATA.topLosers = result.topLosers;
|
|
78
|
+
DATA.sparklines = result.sparklines;
|
|
79
|
+
DATA.chartData = result.chartData;
|
|
80
|
+
DATA.macro = macro || {
|
|
81
|
+
marketCap: 0, marketCapChange: 0, globalVolume: 0, globalVolumeChange: 0,
|
|
82
|
+
fearGreedValue: 50, fearGreedClass: 'Neutral', altcoinIndex: 35
|
|
83
|
+
};
|
|
84
|
+
return DATA;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function loadNetworkData() {
|
|
88
|
+
const [epoch, tpsData, blocktimeData, validators, supply] = await Promise.all([
|
|
89
|
+
API.fetchEpochInfo(),
|
|
90
|
+
API.fetchTPS(),
|
|
91
|
+
API.fetchBlocktime(),
|
|
92
|
+
API.fetchValidators(),
|
|
93
|
+
API.fetchSupply(),
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
supply.epoch = epoch.current;
|
|
97
|
+
|
|
98
|
+
// Try to find SOL price from DexScreener if available to calculate totalStakedUsd
|
|
99
|
+
let solPrice = 145.0; // fallback default
|
|
100
|
+
try {
|
|
101
|
+
const solData = await API.fetchTokenData('So11111111111111111111111111111111111111112');
|
|
102
|
+
if (solData && solData.price) solPrice = solData.price;
|
|
103
|
+
} catch (e) {
|
|
104
|
+
// ignore
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Build networkStats in the shape dashboard.js expects
|
|
108
|
+
DATA.networkStats = {
|
|
109
|
+
epoch,
|
|
110
|
+
tps: tpsData,
|
|
111
|
+
blocktime: blocktimeData,
|
|
112
|
+
validators,
|
|
113
|
+
supply,
|
|
114
|
+
stakeData: {
|
|
115
|
+
totalStaked: supply.staked.toFixed(1) + 'M SOL',
|
|
116
|
+
totalStakedUsd: '$' + (supply.staked * solPrice / 1e3).toFixed(1) + 'B',
|
|
117
|
+
activeStakers: '—',
|
|
118
|
+
uniqueWallets: '—',
|
|
119
|
+
biggestStake: '—',
|
|
120
|
+
medianStake: '—',
|
|
121
|
+
meanStake: '—',
|
|
122
|
+
filterApy: supply.stakingApy + '%',
|
|
123
|
+
updated: 'just now',
|
|
124
|
+
},
|
|
125
|
+
// Stake graph — approximate from epoch data
|
|
126
|
+
stakeGraph: Array.from({ length: 8 }, (_, i) => ({
|
|
127
|
+
epoch: epoch.current - (7 - i) * 50,
|
|
128
|
+
sol: parseFloat((supply.staked * (0.95 + Math.random() * 0.1)).toFixed(2)),
|
|
129
|
+
})).concat([{ epoch: epoch.current, sol: supply.staked }]),
|
|
130
|
+
stakeDistribution: [], // Would need a staking indexer
|
|
131
|
+
};
|
|
132
|
+
return DATA;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function loadWalletData(address) {
|
|
136
|
+
const [result, score] = await Promise.all([
|
|
137
|
+
API.fetchWalletData(address),
|
|
138
|
+
API.fetchFairScaleScore(address)
|
|
139
|
+
]);
|
|
140
|
+
result.fairScale = score;
|
|
141
|
+
DATA.wallet = result;
|
|
142
|
+
return DATA;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function loadTokenData(mintOrSymbol, timeframe) {
|
|
146
|
+
const [result, socials] = await Promise.all([
|
|
147
|
+
API.fetchTokenData(mintOrSymbol, timeframe),
|
|
148
|
+
API.fetchTwitterRSS(mintOrSymbol)
|
|
149
|
+
]);
|
|
150
|
+
DATA.token = result;
|
|
151
|
+
DATA.tokenSocials = socials;
|
|
152
|
+
return DATA;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function loadNewsData() {
|
|
156
|
+
DATA.newsLoading = true;
|
|
157
|
+
const [items, defaultSocials] = await Promise.all([
|
|
158
|
+
API.fetchNewsAggregated(),
|
|
159
|
+
API.fetchTwitterRSS('solana')
|
|
160
|
+
]);
|
|
161
|
+
DATA.news = items;
|
|
162
|
+
if (defaultSocials) DATA.tokenSocials = defaultSocials;
|
|
163
|
+
DATA.newsLastUpdated = new Date();
|
|
164
|
+
DATA.newsLoading = false;
|
|
165
|
+
return DATA;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ── Explorer Data Loaders ─────────────────────────────────
|
|
169
|
+
async function loadExplorerList() {
|
|
170
|
+
DATA.explorer.loading = true;
|
|
171
|
+
try {
|
|
172
|
+
const list = await API.fetchLatestTransactions();
|
|
173
|
+
DATA.explorer.list = list;
|
|
174
|
+
DATA.explorer.error = null;
|
|
175
|
+
} catch (e) {
|
|
176
|
+
DATA.explorer.error = e.message;
|
|
177
|
+
}
|
|
178
|
+
DATA.explorer.loading = false;
|
|
179
|
+
return DATA;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function loadExplorerDetails(signature) {
|
|
183
|
+
DATA.explorer.loading = true;
|
|
184
|
+
DATA.explorer.details = null;
|
|
185
|
+
try {
|
|
186
|
+
const details = await API.fetchTransactionDetails(signature);
|
|
187
|
+
if (details.error) throw new Error(details.error);
|
|
188
|
+
DATA.explorer.details = details;
|
|
189
|
+
DATA.explorer.error = null;
|
|
190
|
+
} catch (e) {
|
|
191
|
+
DATA.explorer.error = e.message;
|
|
192
|
+
}
|
|
193
|
+
DATA.explorer.loading = false;
|
|
194
|
+
return DATA;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = { DATA, loadMarketData, loadNetworkData, loadWalletData, loadTokenData, loadNewsData, loadExplorerList, loadExplorerDetails };
|
package/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Force truecolor for Blessed layout engine on Windows
|
|
2
|
+
process.env.COLORTERM = 'truecolor';
|
|
3
|
+
|
|
4
|
+
// Load .env FIRST — before any other require() reads process.env
|
|
5
|
+
require('dotenv').config({ path: require('path').resolve(__dirname, '.env') });
|
|
6
|
+
|
|
7
|
+
const { program } = require('commander');
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
const clear = require('clear');
|
|
10
|
+
const { renderWallet } = require('./panels/wallet');
|
|
11
|
+
const { renderToken } = require('./panels/token');
|
|
12
|
+
|
|
13
|
+
const { startDashboard } = require('./panels/dashboard');
|
|
14
|
+
|
|
15
|
+
program
|
|
16
|
+
.name('st')
|
|
17
|
+
.description(chalk.hex('#00FF88').bold('Solana TUI Explorer (ST) — On-Chain Developer TUI for Solana'))
|
|
18
|
+
.version('1.0.0');
|
|
19
|
+
|
|
20
|
+
// Dashboard command (Full layout)
|
|
21
|
+
program
|
|
22
|
+
.command('dashboard')
|
|
23
|
+
.alias('d')
|
|
24
|
+
.description('Launch the full-screen developer TUI explorer')
|
|
25
|
+
.action(() => {
|
|
26
|
+
startDashboard();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Header formatting hook (Only run if not dashboard to avoid clearing screen unexpectedly)
|
|
30
|
+
program.hook('preAction', (thisCommand, actionCommand) => {
|
|
31
|
+
if (actionCommand.name() === 'dashboard') return;
|
|
32
|
+
clear();
|
|
33
|
+
console.log(chalk.hex('#00FF88')('==========================================================='));
|
|
34
|
+
console.log(chalk.white.bold(' SOLANA DEV EXPLORER') + chalk.gray(' — On-Chain Inspection TUI'));
|
|
35
|
+
console.log(chalk.hex('#00FF88')('==========================================================='));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// st wallet <ADDRESS>
|
|
39
|
+
program
|
|
40
|
+
.command('wallet [address]')
|
|
41
|
+
.alias('w')
|
|
42
|
+
.description('Inspect any account or wallet balance and details')
|
|
43
|
+
.action((address) => {
|
|
44
|
+
renderWallet(address);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// st token <SYMBOL>
|
|
48
|
+
program
|
|
49
|
+
.command('token [symbol]')
|
|
50
|
+
.alias('t')
|
|
51
|
+
.description('Inspect SPL token parameters and metadata')
|
|
52
|
+
.action((symbol) => {
|
|
53
|
+
renderToken(symbol);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Fallback to dashboard view if no args provided
|
|
57
|
+
if (process.argv.length === 2) {
|
|
58
|
+
process.argv.push('dashboard');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
program.parse(process.argv);
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "solana-tui-explorer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"bin": {
|
|
6
|
+
"solana-tui-explorer": "bin/st.js",
|
|
7
|
+
"st": "bin/st.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"panels",
|
|
12
|
+
"api.js",
|
|
13
|
+
"config.js",
|
|
14
|
+
"data.js",
|
|
15
|
+
"index.js"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/starkdevx/Solana-TUI-Explorer.git"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/starkdevx/Solana-TUI-Explorer#readme",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/starkdevx/Solana-TUI-Explorer/issues"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"start": "node ./bin/st.js",
|
|
27
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"solana",
|
|
31
|
+
"tui",
|
|
32
|
+
"explorer",
|
|
33
|
+
"crypto",
|
|
34
|
+
"cli"
|
|
35
|
+
],
|
|
36
|
+
"author": "Superteam Builder",
|
|
37
|
+
"license": "ISC",
|
|
38
|
+
"description": "The ultimate Information Layer for the Solana ecosystem in a beautifully designed terminal.",
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"bless": "^4.0.4",
|
|
41
|
+
"blessed": "^0.1.81",
|
|
42
|
+
"blessed-contrib": "^4.11.0",
|
|
43
|
+
"chalk": "^4.1.2",
|
|
44
|
+
"clear": "^0.1.0",
|
|
45
|
+
"cli-table3": "^0.6.5",
|
|
46
|
+
"commander": "^14.0.3",
|
|
47
|
+
"dotenv": "^17.4.2",
|
|
48
|
+
"inquirer": "^8.2.7",
|
|
49
|
+
"ora": "^5.4.1"
|
|
50
|
+
}
|
|
51
|
+
}
|