@darksol/terminal 0.7.2 → 0.8.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.
- package/README.md +13 -5
- package/package.json +1 -1
- package/skill/SKILL.md +19 -6
- package/src/cli.js +94 -3
- package/src/config/keys.js +8 -0
- package/src/services/casino.js +26 -76
- package/src/services/lifi.js +713 -0
- package/src/trading/index.js +1 -0
- package/src/web/commands.js +222 -8
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ A unified CLI for market intel, trading, AI-powered analysis, on-chain oracle, c
|
|
|
15
15
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
16
16
|
[](https://nodejs.org/)
|
|
17
17
|
|
|
18
|
-
- Current release: **0.
|
|
18
|
+
- Current release: **0.8.1**
|
|
19
19
|
- Changelog: `CHANGELOG.md`
|
|
20
20
|
|
|
21
21
|
## Install
|
|
@@ -48,9 +48,14 @@ darksol watch AERO --above 2.0
|
|
|
48
48
|
# Gas estimates
|
|
49
49
|
darksol gas base
|
|
50
50
|
|
|
51
|
-
# Swap tokens (Uniswap V3
|
|
51
|
+
# Swap tokens (LI.FI — best route across 31 DEXs, Uniswap V3 fallback)
|
|
52
52
|
darksol trade swap -i ETH -o USDC -a 0.1
|
|
53
53
|
|
|
54
|
+
# Cross-chain bridge (60+ chains via LI.FI)
|
|
55
|
+
darksol bridge send --from base --to arbitrum --token ETH -a 0.1
|
|
56
|
+
darksol bridge status 0xTxHash...
|
|
57
|
+
darksol bridge chains
|
|
58
|
+
|
|
54
59
|
# AI trading assistant
|
|
55
60
|
darksol ai chat
|
|
56
61
|
|
|
@@ -71,7 +76,8 @@ darksol agent start main
|
|
|
71
76
|
|
|
72
77
|
- Arrow-key menus (`↑/↓` + `Enter`) for wallet/config/trade flows
|
|
73
78
|
- **Interactive send** — token → recipient → amount → password → on-chain transfer
|
|
74
|
-
- **Interactive swap** — pair picker (presets + custom) → amount → password → Uniswap V3
|
|
79
|
+
- **Interactive swap** — pair picker (presets + custom) → amount → password → LI.FI execution (Uniswap V3 fallback)
|
|
80
|
+
- **Interactive bridge** — source chain → dest chain → token → amount → password → cross-chain via LI.FI
|
|
75
81
|
- **Interactive snipe** — contract input → amount → password → fast buy
|
|
76
82
|
- Wallet picker + wallet action menu (receive/send/portfolio/history/switch chain)
|
|
77
83
|
- Agent signer control center (`agent`) with guided wallet selection + start/stop/status
|
|
@@ -87,7 +93,8 @@ Useful web-shell commands:
|
|
|
87
93
|
|
|
88
94
|
```bash
|
|
89
95
|
help # clickable command menu (arrow keys + Enter)
|
|
90
|
-
trade # interactive swap / snipe menu
|
|
96
|
+
trade # interactive swap / snipe / bridge menu
|
|
97
|
+
bridge # cross-chain bridge (LI.FI)
|
|
91
98
|
send # interactive token transfer
|
|
92
99
|
wallet # interactive wallet picker and actions
|
|
93
100
|
keys # provider status + interactive add/update
|
|
@@ -104,7 +111,8 @@ ai <prompt> # chat with trading assistant
|
|
|
104
111
|
| `wallet` | Create/import/manage encrypted EVM wallets | Free |
|
|
105
112
|
| `send` | Send ETH or ERC-20 tokens | Gas only |
|
|
106
113
|
| `receive` | Show receive address + chain safety hints | Free |
|
|
107
|
-
| `trade` | Swap (Uniswap V3
|
|
114
|
+
| `trade` | Swap via LI.FI (31 DEXs) + Uniswap V3 fallback, snipe | Gas only |
|
|
115
|
+
| `bridge` | Cross-chain bridge via LI.FI (60 chains, 27 bridges) | Gas only |
|
|
108
116
|
| `dca` | Dollar-cost averaging engine | Gas only |
|
|
109
117
|
| `ai` | LLM-powered trading assistant & intent execution | Provider dependent |
|
|
110
118
|
| `agent` | Secure agent signer (PK-isolated proxy) | Free |
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -7,7 +7,7 @@ description: "DARKSOL Terminal — unified CLI + x402 platform for trading, wall
|
|
|
7
7
|
|
|
8
8
|
**All DARKSOL services. One terminal. Zero trust required. 🌑**
|
|
9
9
|
|
|
10
|
-
`@darksol/terminal` v0.
|
|
10
|
+
`@darksol/terminal` v0.8.0 | npm: `npm install -g @darksol/terminal`
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -63,10 +63,11 @@ darksol wallet use <name> # Set active wallet
|
|
|
63
63
|
darksol wallet export [name] # Export (password required for PK)
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
### 📊 Trading (
|
|
66
|
+
### 📊 Trading (60+ chains via LI.FI)
|
|
67
67
|
```bash
|
|
68
|
-
darksol trade swap # Interactive swap (
|
|
69
|
-
darksol trade swap -i ETH -o USDC -a 0.1 #
|
|
68
|
+
darksol trade swap # Interactive swap (LI.FI — best route across 31 DEXs)
|
|
69
|
+
darksol trade swap -i ETH -o USDC -a 0.1 # LI.FI swap with Uniswap V3 fallback
|
|
70
|
+
darksol trade swap -i ETH -o USDC -a 0.1 --direct # Force direct Uniswap V3 (skip LI.FI)
|
|
70
71
|
darksol trade swap -i ETH -o USDC -a 0.1 -p "pw" -y # Non-interactive (automation/cron)
|
|
71
72
|
darksol trade pairs # Show common pairs for active chain
|
|
72
73
|
darksol trade snipe <token> -a 0.05 # Fast buy with gas boost
|
|
@@ -76,8 +77,20 @@ darksol send # Interactive ETH/ERC-20 transfer
|
|
|
76
77
|
darksol receive # Show your address for receiving
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
### 🌉 Cross-Chain Bridge (LI.FI)
|
|
81
|
+
```bash
|
|
82
|
+
darksol bridge send # Interactive bridge flow
|
|
83
|
+
darksol bridge send -f base -t arbitrum --token ETH -a 0.1 # Bridge ETH from Base to Arbitrum
|
|
84
|
+
darksol bridge send -f ethereum -t polygon --token USDC -a 100 -p "pw" -y # Non-interactive
|
|
85
|
+
darksol bridge status <txHash> # Track cross-chain transfer
|
|
86
|
+
darksol bridge status <txHash> -f base -t arbitrum # Faster status with chain hints
|
|
87
|
+
darksol bridge chains # Show all 60+ supported chains
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**LI.FI routing:** Aggregates 27 bridges and 31 DEXs across 60 chains. Finds optimal route automatically.
|
|
91
|
+
**Swap routing:** LI.FI primary, Uniswap V3 fallback. Use `--direct` to skip LI.FI.
|
|
92
|
+
**API key:** Free tier works without key (200 req/2hr). Higher limits: `darksol keys add lifi`
|
|
93
|
+
**Supported chains:** Base, Ethereum, Polygon, Arbitrum, Optimism, Avalanche, BSC, zkSync, Scroll, Linea, + 50 more
|
|
81
94
|
|
|
82
95
|
### 📈 DCA (Dollar-Cost Averaging)
|
|
83
96
|
```bash
|
package/src/cli.js
CHANGED
|
@@ -13,6 +13,7 @@ import { startWebShell } from './web/server.js';
|
|
|
13
13
|
import { executeSwap } from './trading/swap.js';
|
|
14
14
|
import { snipeToken, watchSnipe } from './trading/snipe.js';
|
|
15
15
|
import { createDCA, listDCA, cancelDCA, runDCA } from './trading/dca.js';
|
|
16
|
+
import { executeLifiSwap, executeLifiBridge, checkBridgeStatus, showSupportedChains } from './services/lifi.js';
|
|
16
17
|
import { topMovers, tokenDetail, compareTokens } from './services/market.js';
|
|
17
18
|
import { oracleFlip, oracleDice, oracleNumber, oracleShuffle, oracleHealth } from './services/oracle.js';
|
|
18
19
|
import { casinoBet, casinoTables, casinoStats, casinoReceipt, casinoHealth, casinoVerify } from './services/casino.js';
|
|
@@ -113,7 +114,7 @@ export function cli(argv) {
|
|
|
113
114
|
|
|
114
115
|
trade
|
|
115
116
|
.command('swap')
|
|
116
|
-
.description('Swap tokens via
|
|
117
|
+
.description('Swap tokens via LI.FI (58 chains, 31 DEXs) with Uniswap fallback')
|
|
117
118
|
.option('-i, --in <token>', 'Token to sell (symbol or address)')
|
|
118
119
|
.option('-o, --out <token>', 'Token to buy (symbol or address)')
|
|
119
120
|
.option('-a, --amount <amount>', 'Amount to swap')
|
|
@@ -121,6 +122,7 @@ export function cli(argv) {
|
|
|
121
122
|
.option('-w, --wallet <name>', 'Wallet to use')
|
|
122
123
|
.option('-p, --password <pw>', 'Wallet password (non-interactive)')
|
|
123
124
|
.option('-y, --yes', 'Skip confirmation')
|
|
125
|
+
.option('--direct', 'Force direct Uniswap V3 (skip LI.FI)')
|
|
124
126
|
.action(async (opts) => {
|
|
125
127
|
let tokenIn = opts.in;
|
|
126
128
|
let tokenOut = opts.out;
|
|
@@ -138,7 +140,7 @@ export function cli(argv) {
|
|
|
138
140
|
amount = answers.amount;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
|
|
143
|
+
const swapOpts = {
|
|
142
144
|
tokenIn,
|
|
143
145
|
tokenOut,
|
|
144
146
|
amount,
|
|
@@ -146,7 +148,30 @@ export function cli(argv) {
|
|
|
146
148
|
wallet: opts.wallet,
|
|
147
149
|
password: opts.password,
|
|
148
150
|
confirm: opts.yes ? true : undefined,
|
|
149
|
-
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Try LI.FI first (unless --direct flag)
|
|
154
|
+
if (!opts.direct) {
|
|
155
|
+
try {
|
|
156
|
+
const result = await executeLifiSwap(swapOpts);
|
|
157
|
+
if (result?.success) return;
|
|
158
|
+
// If LI.FI failed (not cancelled), fall back to direct
|
|
159
|
+
if (result?.error !== 'cancelled') {
|
|
160
|
+
const { warn: showWarn, info: showInfo } = await import('./ui/components.js');
|
|
161
|
+
showWarn('LI.FI route failed — falling back to direct Uniswap V3...');
|
|
162
|
+
console.log('');
|
|
163
|
+
} else {
|
|
164
|
+
return; // User cancelled, don't fallback
|
|
165
|
+
}
|
|
166
|
+
} catch {
|
|
167
|
+
const { warn: showWarn } = await import('./ui/components.js');
|
|
168
|
+
showWarn('LI.FI unavailable — falling back to direct Uniswap V3...');
|
|
169
|
+
console.log('');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Direct Uniswap V3 fallback
|
|
174
|
+
return executeSwap(swapOpts);
|
|
150
175
|
});
|
|
151
176
|
|
|
152
177
|
trade
|
|
@@ -193,6 +218,71 @@ export function cli(argv) {
|
|
|
193
218
|
console.log('');
|
|
194
219
|
});
|
|
195
220
|
|
|
221
|
+
// ═══════════════════════════════════════
|
|
222
|
+
// BRIDGE COMMANDS (LI.FI)
|
|
223
|
+
// ═══════════════════════════════════════
|
|
224
|
+
const bridge = program
|
|
225
|
+
.command('bridge')
|
|
226
|
+
.description('Cross-chain bridge — move tokens between chains via LI.FI');
|
|
227
|
+
|
|
228
|
+
bridge
|
|
229
|
+
.command('send')
|
|
230
|
+
.description('Bridge tokens to another chain')
|
|
231
|
+
.option('-f, --from <chain>', 'Source chain (e.g. base, ethereum)')
|
|
232
|
+
.option('-t, --to <chain>', 'Destination chain (e.g. arbitrum, optimism)')
|
|
233
|
+
.option('--token <symbol>', 'Token to bridge (e.g. ETH, USDC)', 'ETH')
|
|
234
|
+
.option('-a, --amount <amount>', 'Amount to bridge')
|
|
235
|
+
.option('-s, --slippage <percent>', 'Max slippage %', '0.5')
|
|
236
|
+
.option('-w, --wallet <name>', 'Wallet to use')
|
|
237
|
+
.option('-p, --password <pw>', 'Wallet password (non-interactive)')
|
|
238
|
+
.option('-y, --yes', 'Skip confirmation')
|
|
239
|
+
.action(async (opts) => {
|
|
240
|
+
let fromChain = opts.from;
|
|
241
|
+
let toChain = opts.to;
|
|
242
|
+
let token = opts.token;
|
|
243
|
+
let amount = opts.amount;
|
|
244
|
+
|
|
245
|
+
if (!fromChain || !toChain || !amount) {
|
|
246
|
+
const inquirer = (await import('inquirer')).default;
|
|
247
|
+
const answers = await inquirer.prompt([
|
|
248
|
+
{ type: 'input', name: 'fromChain', message: 'Source chain:', default: fromChain || getConfig('chain') || 'base' },
|
|
249
|
+
{ type: 'input', name: 'toChain', message: 'Destination chain:', default: toChain || 'arbitrum' },
|
|
250
|
+
{ type: 'input', name: 'token', message: 'Token to bridge:', default: token || 'ETH' },
|
|
251
|
+
{ type: 'input', name: 'amount', message: 'Amount:', default: amount || '0.1' },
|
|
252
|
+
]);
|
|
253
|
+
fromChain = answers.fromChain;
|
|
254
|
+
toChain = answers.toChain;
|
|
255
|
+
token = answers.token;
|
|
256
|
+
amount = answers.amount;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return executeLifiBridge({
|
|
260
|
+
fromChain,
|
|
261
|
+
toChain,
|
|
262
|
+
token,
|
|
263
|
+
amount,
|
|
264
|
+
slippage: parseFloat(opts.slippage),
|
|
265
|
+
wallet: opts.wallet,
|
|
266
|
+
password: opts.password,
|
|
267
|
+
confirm: opts.yes ? true : undefined,
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
bridge
|
|
272
|
+
.command('status <txHash>')
|
|
273
|
+
.description('Check bridge transfer status')
|
|
274
|
+
.option('-f, --from <chain>', 'Source chain')
|
|
275
|
+
.option('-t, --to <chain>', 'Destination chain')
|
|
276
|
+
.action((txHash, opts) => checkBridgeStatus(txHash, {
|
|
277
|
+
fromChain: opts.from,
|
|
278
|
+
toChain: opts.to,
|
|
279
|
+
}));
|
|
280
|
+
|
|
281
|
+
bridge
|
|
282
|
+
.command('chains')
|
|
283
|
+
.description('Show all supported chains')
|
|
284
|
+
.action(() => showSupportedChains());
|
|
285
|
+
|
|
196
286
|
// ═══════════════════════════════════════
|
|
197
287
|
// DCA COMMANDS
|
|
198
288
|
// ═══════════════════════════════════════
|
|
@@ -1109,6 +1199,7 @@ function showCommandList() {
|
|
|
1109
1199
|
['watch', 'Live price monitoring + alerts'],
|
|
1110
1200
|
['gas', 'Gas prices & cost estimates'],
|
|
1111
1201
|
['trade', 'Swap tokens, snipe, trading'],
|
|
1202
|
+
['bridge', 'Cross-chain bridge (LI.FI)'],
|
|
1112
1203
|
['dca', 'Dollar-cost averaging orders'],
|
|
1113
1204
|
['ai chat', 'Standalone AI chat session'],
|
|
1114
1205
|
['ai execute', 'Parse + execute a trade via AI'],
|
package/src/config/keys.js
CHANGED
|
@@ -178,6 +178,14 @@ export const SERVICES = {
|
|
|
178
178
|
docsUrl: 'https://developers.paraswap.network',
|
|
179
179
|
validate: (key) => key.length > 5,
|
|
180
180
|
},
|
|
181
|
+
lifi: {
|
|
182
|
+
name: 'LI.FI',
|
|
183
|
+
category: 'trading',
|
|
184
|
+
description: 'Cross-chain swaps & bridges — 58 chains, 27 bridges, 31 DEXs',
|
|
185
|
+
envVar: 'LIFI_API_KEY',
|
|
186
|
+
docsUrl: 'https://docs.li.fi/api-reference/rate-limits',
|
|
187
|
+
validate: (key) => key.length > 20,
|
|
188
|
+
},
|
|
181
189
|
};
|
|
182
190
|
|
|
183
191
|
// ──────────────────────────────────────────────────
|
package/src/services/casino.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { fetchJSON } from '../utils/fetch.js';
|
|
2
|
-
import
|
|
3
|
-
import { ethers } from 'ethers';
|
|
4
|
-
import { getServiceURL, getConfig, getRPC } from '../config/store.js';
|
|
2
|
+
import { getServiceURL, getConfig } from '../config/store.js';
|
|
5
3
|
import { theme } from '../ui/theme.js';
|
|
6
4
|
import { spinner, kvDisplay, success, error, warn, info, table } from '../ui/components.js';
|
|
7
5
|
import { showSection } from '../ui/banner.js';
|
|
@@ -181,82 +179,36 @@ export async function casinoBet(gameType, betParams = {}, opts = {}) {
|
|
|
181
179
|
return;
|
|
182
180
|
}
|
|
183
181
|
|
|
184
|
-
// ──
|
|
185
|
-
const
|
|
186
|
-
const
|
|
187
|
-
const USDC_AMOUNT = '1000000'; // 1 USDC (6 decimals)
|
|
182
|
+
// ── Place bet via x402 (EIP-3009 auto-pay) ──
|
|
183
|
+
const signerToken = process.env.DARKSOL_SIGNER_TOKEN || getConfig('signerToken') || null;
|
|
184
|
+
const signerUp = await isSignerRunning(signerToken);
|
|
188
185
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
try {
|
|
193
|
-
// Try agent signer first
|
|
194
|
-
const signerToken = process.env.DARKSOL_SIGNER_TOKEN || getConfig('signerToken') || null;
|
|
195
|
-
const signerUp = await isSignerRunning(signerToken);
|
|
196
|
-
|
|
197
|
-
if (signerUp) {
|
|
198
|
-
// Use agent signer to send USDC
|
|
199
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
200
|
-
if (signerToken) headers.Authorization = `Bearer ${signerToken}`;
|
|
201
|
-
|
|
202
|
-
// ERC-20 transfer calldata: transfer(address,uint256)
|
|
203
|
-
const iface = new ethers.Interface(['function transfer(address to, uint256 amount) returns (bool)']);
|
|
204
|
-
const txData = iface.encodeFunctionData('transfer', [HOUSE_WALLET, USDC_AMOUNT]);
|
|
205
|
-
|
|
206
|
-
const resp = await fetch('http://127.0.0.1:18790/send', {
|
|
207
|
-
method: 'POST',
|
|
208
|
-
headers,
|
|
209
|
-
body: JSON.stringify({ to: USDC_BASE, data: txData, value: '0' }),
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
if (!resp.ok) {
|
|
213
|
-
const errText = await resp.text();
|
|
214
|
-
throw new Error(`Signer refused: ${errText}`);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const result = await resp.json();
|
|
218
|
-
paymentTxHash = result.txHash || result.hash;
|
|
219
|
-
} else {
|
|
220
|
-
// Try wallet directly (needs password)
|
|
221
|
-
const activeWallet = getConfig('activeWallet');
|
|
222
|
-
if (!activeWallet) throw new Error('No wallet configured. Set one: darksol wallet use <name>');
|
|
223
|
-
|
|
224
|
-
const { decryptKey } = await import('../wallet/keystore.js');
|
|
225
|
-
const password = process.env.DARKSOL_WALLET_PASSWORD;
|
|
226
|
-
if (!password) {
|
|
227
|
-
paymentSpin.fail('Payment requires agent signer or DARKSOL_WALLET_PASSWORD');
|
|
228
|
-
info('Start agent signer: darksol signer start');
|
|
229
|
-
info('Or set: export DARKSOL_WALLET_PASSWORD=<password>');
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const pk = decryptKey(activeWallet, password);
|
|
234
|
-
const provider = new ethers.JsonRpcProvider(getRPC('base'));
|
|
235
|
-
const wallet = new ethers.Wallet(pk, provider);
|
|
236
|
-
const usdc = new ethers.Contract(USDC_BASE, ['function transfer(address,uint256) returns (bool)'], wallet);
|
|
237
|
-
const tx = await usdc.transfer(HOUSE_WALLET, USDC_AMOUNT);
|
|
238
|
-
const receipt = await tx.wait();
|
|
239
|
-
paymentTxHash = receipt.hash;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
paymentSpin.succeed(`Payment sent: ${paymentTxHash.slice(0, 16)}...`);
|
|
243
|
-
} catch (err) {
|
|
244
|
-
paymentSpin.fail('Payment failed');
|
|
245
|
-
error(err.message);
|
|
246
|
-
if (err.message.includes('insufficient')) {
|
|
247
|
-
info('You need at least 1 USDC on Base to play');
|
|
248
|
-
}
|
|
186
|
+
if (!signerUp) {
|
|
187
|
+
error('Agent signer is required for casino bets (x402 payment).');
|
|
188
|
+
info('Start it: darksol agent start <wallet-name>');
|
|
249
189
|
return;
|
|
250
190
|
}
|
|
251
191
|
|
|
252
|
-
// ── Place the bet with payment proof ──
|
|
253
192
|
const spin = spinner(`Playing ${gameInfo.name}...`).start();
|
|
254
193
|
try {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
194
|
+
const { fetchWithX402 } = await import('../utils/x402.js');
|
|
195
|
+
const result = await fetchWithX402(
|
|
196
|
+
`${getURL()}/api/bet`,
|
|
197
|
+
{
|
|
198
|
+
method: 'POST',
|
|
199
|
+
headers: { 'Content-Type': 'application/json' },
|
|
200
|
+
body: JSON.stringify({ gameType, betParams, agentWallet }),
|
|
201
|
+
},
|
|
202
|
+
{ signerToken, autoSign: true },
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
if (result.error) {
|
|
206
|
+
spin.fail('Payment failed');
|
|
207
|
+
error(result.error);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const data = result.data;
|
|
260
212
|
|
|
261
213
|
if (data.won) {
|
|
262
214
|
spin.succeed(theme.success(`YOU WON! $${data.payoutAmount} USDC`));
|
|
@@ -271,7 +223,7 @@ export async function casinoBet(gameType, betParams = {}, opts = {}) {
|
|
|
271
223
|
['Result', data.result || '-'],
|
|
272
224
|
['Won', data.won ? theme.success('YES! 🎉') : theme.error('No')],
|
|
273
225
|
['Payout', data.won ? `$${data.payoutAmount} USDC` : '$0'],
|
|
274
|
-
['Payment
|
|
226
|
+
['Payment', result.paid ? theme.success('x402 ✓') : theme.dim('unpaid')],
|
|
275
227
|
['Oracle TX', data.oracleTxHash ? data.oracleTxHash.slice(0, 20) + '...' : '-'],
|
|
276
228
|
['Payout TX', data.payoutTxHash ? data.payoutTxHash.slice(0, 20) + '...' : '-'],
|
|
277
229
|
]);
|
|
@@ -286,8 +238,6 @@ export async function casinoBet(gameType, betParams = {}, opts = {}) {
|
|
|
286
238
|
error(err.message);
|
|
287
239
|
if (err.message.includes('not accepting') || err.message.includes('closed')) {
|
|
288
240
|
info('The casino may be temporarily closed. Check: darksol casino status');
|
|
289
|
-
} else if (err.message.includes('payment') || err.message.includes('Payment')) {
|
|
290
|
-
info(`Your USDC was sent (${paymentTxHash.slice(0, 16)}...) — contact support if bet wasn't processed`);
|
|
291
241
|
}
|
|
292
242
|
}
|
|
293
243
|
}
|