diff --git a/index.js b/index.js index 47bc4ade..d29ffb3d 100644 --- a/index.js +++ b/index.js @@ -1,533 +1,1029 @@ -/** @typedef {import('pear-interface')} */ -import fs from 'fs'; -import path from 'path'; -import b4a from 'b4a'; -import PeerWallet from 'trac-wallet'; -import { Peer, Wallet, createConfig as createPeerConfig, ENV as PEER_ENV } from 'trac-peer'; -import { MainSettlementBus } from 'trac-msb/src/index.js'; -import { createConfig as createMsbConfig, ENV as MSB_ENV } from 'trac-msb/src/config/env.js'; -import { ensureTextCodecs } from 'trac-peer/src/textCodec.js'; -import { getPearRuntime, ensureTrailingSlash } from 'trac-peer/src/runnerArgs.js'; -import { Terminal } from 'trac-peer/src/terminal/index.js'; -import SampleProtocol from './contract/protocol.js'; -import SampleContract from './contract/contract.js'; -import { Timer } from './features/timer/index.js'; -import Sidechannel from './features/sidechannel/index.js'; -import ScBridge from './features/sc-bridge/index.js'; - -const { env, storeLabel, flags } = getPearRuntime(); - -const peerStoreNameRaw = - (flags['peer-store-name'] && String(flags['peer-store-name'])) || - env.PEER_STORE_NAME || - storeLabel || - 'peer'; - -const peerStoresDirectory = ensureTrailingSlash( - (flags['peer-stores-directory'] && String(flags['peer-stores-directory'])) || - env.PEER_STORES_DIRECTORY || - 'stores/' -); - -const msbStoreName = - (flags['msb-store-name'] && String(flags['msb-store-name'])) || - env.MSB_STORE_NAME || - `${peerStoreNameRaw}-msb`; - -const msbStoresDirectory = ensureTrailingSlash( - (flags['msb-stores-directory'] && String(flags['msb-stores-directory'])) || - env.MSB_STORES_DIRECTORY || - 'stores/' -); - -const subnetChannel = - (flags['subnet-channel'] && String(flags['subnet-channel'])) || - env.SUBNET_CHANNEL || - 'trac-peer-subnet'; - -const sidechannelsRaw = - (flags['sidechannels'] && String(flags['sidechannels'])) || - (flags['sidechannel'] && String(flags['sidechannel'])) || - env.SIDECHANNELS || - ''; - -const parseBool = (value, fallback) => { - if (value === undefined || value === null || value === '') return fallback; - return ['1', 'true', 'yes', 'on'].includes(String(value).trim().toLowerCase()); -}; - -const parseKeyValueList = (raw) => { - if (!raw) return []; - return String(raw) - .split(',') - .map((entry) => String(entry || '').trim()) - .filter((entry) => entry.length > 0) - .map((entry) => { - const idx = entry.indexOf(':'); - const alt = entry.indexOf('='); - const splitAt = idx >= 0 ? idx : alt; - if (splitAt <= 0) return null; - const key = entry.slice(0, splitAt).trim(); - const value = entry.slice(splitAt + 1).trim(); - if (!key || !value) return null; - return [key, value]; - }) - .filter(Boolean); -}; - -const parseCsvList = (raw) => { - if (!raw) return null; - return String(raw) - .split(',') - .map((value) => value.trim()) - .filter((value) => value.length > 0); -}; - -const parseWelcomeValue = (raw) => { - if (!raw) return null; - let text = String(raw || '').trim(); - if (!text) return null; - if (text.startsWith('@')) { - try { - const filePath = path.resolve(text.slice(1)); - text = String(fs.readFileSync(filePath, 'utf8') || '').trim(); - if (!text) return null; - } catch (_e) { - return null; - } - } - if (text.startsWith('b64:')) text = text.slice(4); - if (text.startsWith('{')) { - try { - return JSON.parse(text); - } catch (_e) { - return null; - } - } - try { - const decoded = b4a.toString(b4a.from(text, 'base64')); - return JSON.parse(decoded); - } catch (_e) {} - return null; -}; - -const sidechannelDebugRaw = - (flags['sidechannel-debug'] && String(flags['sidechannel-debug'])) || - env.SIDECHANNEL_DEBUG || - ''; -const sidechannelDebug = parseBool(sidechannelDebugRaw, false); -const sidechannelQuietRaw = - (flags['sidechannel-quiet'] && String(flags['sidechannel-quiet'])) || - env.SIDECHANNEL_QUIET || - ''; -const sidechannelQuiet = parseBool(sidechannelQuietRaw, false); -const sidechannelMaxBytesRaw = - (flags['sidechannel-max-bytes'] && String(flags['sidechannel-max-bytes'])) || - env.SIDECHANNEL_MAX_BYTES || - ''; -const sidechannelMaxBytes = Number.parseInt(sidechannelMaxBytesRaw, 10); -const sidechannelAllowRemoteOpenRaw = - (flags['sidechannel-allow-remote-open'] && String(flags['sidechannel-allow-remote-open'])) || - env.SIDECHANNEL_ALLOW_REMOTE_OPEN || - ''; -const sidechannelAllowRemoteOpen = parseBool(sidechannelAllowRemoteOpenRaw, true); -const sidechannelAutoJoinRaw = - (flags['sidechannel-auto-join'] && String(flags['sidechannel-auto-join'])) || - env.SIDECHANNEL_AUTO_JOIN || - ''; -const sidechannelAutoJoin = parseBool(sidechannelAutoJoinRaw, false); -const sidechannelPowRaw = - (flags['sidechannel-pow'] && String(flags['sidechannel-pow'])) || - env.SIDECHANNEL_POW || - ''; -const sidechannelPowEnabled = parseBool(sidechannelPowRaw, true); -const sidechannelPowDifficultyRaw = - (flags['sidechannel-pow-difficulty'] && String(flags['sidechannel-pow-difficulty'])) || - env.SIDECHANNEL_POW_DIFFICULTY || - '12'; -const sidechannelPowDifficulty = Number.parseInt(sidechannelPowDifficultyRaw, 10); -const sidechannelPowEntryRaw = - (flags['sidechannel-pow-entry'] && String(flags['sidechannel-pow-entry'])) || - env.SIDECHANNEL_POW_ENTRY || - ''; -const sidechannelPowRequireEntry = parseBool(sidechannelPowEntryRaw, false); -const sidechannelPowChannelsRaw = - (flags['sidechannel-pow-channels'] && String(flags['sidechannel-pow-channels'])) || - env.SIDECHANNEL_POW_CHANNELS || - ''; -const sidechannelPowChannels = sidechannelPowChannelsRaw - ? sidechannelPowChannelsRaw - .split(',') - .map((value) => value.trim()) - .filter((value) => value.length > 0) - : null; -const sidechannelInviteRequiredRaw = - (flags['sidechannel-invite-required'] && String(flags['sidechannel-invite-required'])) || - env.SIDECHANNEL_INVITE_REQUIRED || - ''; -const sidechannelInviteRequired = parseBool(sidechannelInviteRequiredRaw, false); -const sidechannelInviteChannelsRaw = - (flags['sidechannel-invite-channels'] && String(flags['sidechannel-invite-channels'])) || - env.SIDECHANNEL_INVITE_CHANNELS || - ''; -const sidechannelInviteChannels = sidechannelInviteChannelsRaw - ? sidechannelInviteChannelsRaw - .split(',') - .map((value) => value.trim()) - .filter((value) => value.length > 0) - : null; -const sidechannelInvitePrefixesRaw = - (flags['sidechannel-invite-prefixes'] && String(flags['sidechannel-invite-prefixes'])) || - env.SIDECHANNEL_INVITE_PREFIXES || - ''; -const sidechannelInvitePrefixes = sidechannelInvitePrefixesRaw - ? sidechannelInvitePrefixesRaw - .split(',') - .map((value) => value.trim()) - .filter((value) => value.length > 0) - : null; -const sidechannelInviterKeysRaw = - (flags['sidechannel-inviter-keys'] && String(flags['sidechannel-inviter-keys'])) || - env.SIDECHANNEL_INVITER_KEYS || - ''; -const sidechannelInviterKeys = sidechannelInviterKeysRaw - ? sidechannelInviterKeysRaw - .split(',') - .map((value) => value.trim()) - .filter((value) => value.length > 0) - : []; -const sidechannelInviteTtlRaw = - (flags['sidechannel-invite-ttl'] && String(flags['sidechannel-invite-ttl'])) || - env.SIDECHANNEL_INVITE_TTL || - '604800'; -const sidechannelInviteTtlSec = Number.parseInt(sidechannelInviteTtlRaw, 10); -const sidechannelInviteTtlMs = Number.isFinite(sidechannelInviteTtlSec) - ? Math.max(sidechannelInviteTtlSec, 0) * 1000 - : 0; -const sidechannelOwnerRaw = - (flags['sidechannel-owner'] && String(flags['sidechannel-owner'])) || - env.SIDECHANNEL_OWNER || - ''; -const sidechannelOwnerEntries = parseKeyValueList(sidechannelOwnerRaw); -const sidechannelOwnerMap = new Map(); -for (const [channel, key] of sidechannelOwnerEntries) { - const normalizedKey = key.trim().toLowerCase(); - if (channel && normalizedKey) sidechannelOwnerMap.set(channel.trim(), normalizedKey); + + + + + +AutoDEX Agent — Intercom Autonomous Trading · Trac Network + + + + + + +
+ + +
+ + +
+
+ BTC / USDT + $96,420 + ▲ 1.24% +
+
+ SOL Slot + 325,841,182 + ▲ LIVE +
+
+ Agents + 4 Active + ▲ Running +
+
+ P&L Today + +$1,285 + ▲ 22 trades +
+
+ +
+
⬡ 14 Peers
+
P2P LIVE
+
+
+ + +
+
📡 Events
+
+
+
+
+ + +
+ + +
+ +
+
+ Active Agents + 3 running · 1 paused +
+ + +
+
+
+
+ AutoBuy · BTC / USDT +
+ RUNNING +
+
+
IF price < $96,200
+
AND rsi_14 < 40
+
THEN swap 50,000 sats via LN → SOL
+
+
+
12Executions
+
+$842P&L
+
$96,200Trigger
+
+
+
+ + + +
+
+ + +
+
+
+
+ AutoSell · BTC / USDT +
+ RUNNING +
+
+
IF price > $97,500
+
AND volume_1h > 2.0 BTC
+
THEN swap 30,000 sats via LN → SOL
+
+
+
7Executions
+
+$316P&L
+
$97,500Trigger
+
+
+
+ + + +
+
+ + +
+
+
+
+ Arb Monitor · Spread +
+ PAUSED +
+
+
IF spread > 0.05%
+
AND ln_liquidity > 100k sats
+
THEN execute arb swap both legs
+
+
+
3Executions
+
+$127P&L
+
0.019%Spread
+
+
+
+ + + +
+
+ + +
+
+
+
+ Chain Watcher · Solana +
+ RUNNING +
+
+
IF escrow_slot confirmed
+
AND preimage present
+
THEN auto_claim USDT escrow
+
+
+
28Watched
+
100%Claimed
+
325.8MSOL Slot
+
+
+
+ + + +
+
+
+ + +
+
Build New Agent
+
+
⚙ Define Trigger Conditions
+
+
Agent Type
+ +
+
+
Token In
+
+
Token Out
+
+
+
+
Condition
+
+
Value
+
+
+
+
Amount (sats)
+
+
Max Fee %
+
+
+
+
Sidechannel
+ +
+ +
+
+ + +
+
P2P Sidechannels
+
0000intercomswapbtcusdt14
+
0000intercom31
+
swap:trade_9f3c…2
+
swap:trade_a12d…2
+
swap:trade_b78e…2
+
+ +
+ + + +
+ +
+
+
+ $96,420 + +$1,182 (1.24%) +
+
+
24H High $97,104
+
24H Low  $94,828
+
Volume   $2.41M
+
+
+ +
+ + + + +
+ +
+ + + + + + + + + + + + + + + + SELL $97,500 + + BUY $96,200 + + + + + + +
+
+ +
+
Total P&L
+$1,285
+
Executions
22
+
Success Rate
97.3%
+
Avg Latency
28s
+
+ +
+
+ Agent Event Log + CLEAR +
+
+ +
+ + + +
+ +
+
Condition Monitor
+
BTC < $96,200 (AutoBuy)
$96,420 ✗
+
BTC > $97,500 (AutoSell)
$96,420 ✗
+
Spread > 0.05%
0.019% ⚠
+
LN Liquidity > 100k sats
482k ✓
+
SOL RPC reachable
42ms ✓
+
P2P Peers > 3
14 ✓
+
RSI(14) < 40
48.2 ✗
+
+ +
+
Order Depth
+
+
Spread · $18.40 · 0.019%
+
+
+ +
+
Wallet Balances
+
+
Bitcoin
Lightning
+
0.4821 BTC≈ $46,448
+
+
+
USDT
Solana SPL
+
12,480.00≈ $12,480
+
+
+
SOL
Gas reserve
+
2.41 SOL≈ $408
+
+
+
TNK
Trac Network
+
5,000 TNKGas token
+
+
+ +
+
7-Day Performance
+
+
MonTueWedThuFriSatSun
+
+
+8.4%Week ROI
+
73Total Swaps
+
$24Avg Profit
+
97%Win Rate
+
+
+ +
+ +
+ + + + + +
+ + + +