@darksol/terminal 0.6.2 → 0.6.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darksol/terminal",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "DARKSOL Terminal — unified CLI for all DARKSOL services. Market intel, trading, oracle, casino, and more.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,10 +1,11 @@
1
1
  import { fetchJSON } from '../utils/fetch.js';
2
2
  import fetch from 'node-fetch';
3
- import { getServiceURL } from '../config/store.js';
4
- import { getConfig } from '../config/store.js';
3
+ import { ethers } from 'ethers';
4
+ import { getServiceURL, getConfig, getRPC } from '../config/store.js';
5
5
  import { theme } from '../ui/theme.js';
6
6
  import { spinner, kvDisplay, success, error, warn, info, table } from '../ui/components.js';
7
7
  import { showSection } from '../ui/banner.js';
8
+ import { isSignerRunning } from '../utils/x402.js';
8
9
 
9
10
  const getURL = () => getServiceURL('casino') || 'https://casino.darksol.net';
10
11
 
@@ -180,12 +181,81 @@ export async function casinoBet(gameType, betParams = {}, opts = {}) {
180
181
  return;
181
182
  }
182
183
 
184
+ // ── Payment: Send 1 USDC to the house ──
185
+ const HOUSE_WALLET = '0x7B0a6330121B26100D47BCcd5640cc6617F8adA7';
186
+ const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
187
+ const USDC_AMOUNT = '1000000'; // 1 USDC (6 decimals)
188
+
189
+ const paymentSpin = spinner('Sending $1 USDC to the house...').start();
190
+ let paymentTxHash;
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
+ }
249
+ return;
250
+ }
251
+
252
+ // ── Place the bet with payment proof ──
183
253
  const spin = spinner(`Playing ${gameInfo.name}...`).start();
184
254
  try {
185
255
  const data = await fetchJSON(`${getURL()}/api/bet`, {
186
256
  method: 'POST',
187
257
  headers: { 'Content-Type': 'application/json' },
188
- body: JSON.stringify({ gameType, betParams, agentWallet }),
258
+ body: JSON.stringify({ gameType, betParams, agentWallet, paymentTxHash }),
189
259
  });
190
260
 
191
261
  if (data.won) {
@@ -201,6 +271,7 @@ export async function casinoBet(gameType, betParams = {}, opts = {}) {
201
271
  ['Result', data.result || '-'],
202
272
  ['Won', data.won ? theme.success('YES! 🎉') : theme.error('No')],
203
273
  ['Payout', data.won ? `$${data.payoutAmount} USDC` : '$0'],
274
+ ['Payment TX', paymentTxHash.slice(0, 20) + '...'],
204
275
  ['Oracle TX', data.oracleTxHash ? data.oracleTxHash.slice(0, 20) + '...' : '-'],
205
276
  ['Payout TX', data.payoutTxHash ? data.payoutTxHash.slice(0, 20) + '...' : '-'],
206
277
  ]);
@@ -215,6 +286,8 @@ export async function casinoBet(gameType, betParams = {}, opts = {}) {
215
286
  error(err.message);
216
287
  if (err.message.includes('not accepting') || err.message.includes('closed')) {
217
288
  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`);
218
291
  }
219
292
  }
220
293
  }