@sherwoodagent/cli 0.81.0 → 0.83.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/dist/{abis-OLIDCWDS.js → abis-ZQ6I3S6L.js} +2 -4
- package/dist/{addresses-EF5OQSKV.js → addresses-MS6BB7AB.js} +3 -3
- package/dist/{agent-VLYILEUP.js → agent-I6AUSTZG.js} +7 -7
- package/dist/{chat-ANE3SNHH.js → chat-5SI7K5FA.js} +8 -8
- package/dist/{chunk-Z7GRB3OQ.js → chunk-4BMAFJKO.js} +6 -6
- package/dist/{chunk-BJ4G3TPP.js → chunk-5BYJ3TGZ.js} +2 -2
- package/dist/{chunk-WUYJ7AS6.js → chunk-5O3KO7ZI.js} +3 -3
- package/dist/{chunk-QSYLZA4Z.js → chunk-7ILOT3SI.js} +2 -2
- package/dist/{chunk-QK3FUTVI.js → chunk-I7NXKJCG.js} +5 -5
- package/dist/{chunk-XW6NDXBA.js → chunk-I7TMY7AS.js} +12 -12
- package/dist/{chunk-XW6NDXBA.js.map → chunk-I7TMY7AS.js.map} +1 -1
- package/dist/{chunk-XDWYX5ZM.js → chunk-MRUTBOMZ.js} +2 -2
- package/dist/{chunk-54WMDJTL.js → chunk-N5RIB6ZZ.js} +386 -5
- package/dist/chunk-N5RIB6ZZ.js.map +1 -0
- package/dist/{chunk-RFJSV3EZ.js → chunk-UK2G5AZG.js} +5 -5
- package/dist/{chunk-TU655ZTV.js → chunk-XSP64L7L.js} +1102 -480
- package/dist/chunk-XSP64L7L.js.map +1 -0
- package/dist/{chunk-K2NEFUEP.js → chunk-ZEZQM42M.js} +5 -5
- package/dist/chunk-ZEZQM42M.js.map +1 -0
- package/dist/{chunk-UO4UITOY.js → chunk-ZTR2GPZO.js} +28 -7
- package/dist/chunk-ZTR2GPZO.js.map +1 -0
- package/dist/{chunk-VJKZDHH3.js → chunk-ZW2VKCFZ.js} +11 -10
- package/dist/chunk-ZW2VKCFZ.js.map +1 -0
- package/dist/{client-25LF2O4P.js → client-Z7LNEG2F.js} +3 -3
- package/dist/{cron-QMLRWDJG.js → cron-E3UAZF5B.js} +1 -1
- package/dist/cron-E3UAZF5B.js.map +1 -0
- package/dist/{eas-HHMRO37P.js → eas-DWBT332K.js} +6 -6
- package/dist/{governor-AL2XUGBE.js → governor-ZVNTHHML.js} +6 -6
- package/dist/index.js +4837 -4576
- package/dist/index.js.map +1 -1
- package/dist/{network-R45QDUYO.js → network-HCFCNZUI.js} +2 -2
- package/dist/{price-QO22NF5Q.js → price-GEUCSTO4.js} +6 -6
- package/dist/{providers-ALMXBRNW.js → providers-PWUJ2AR7.js} +4 -4
- package/dist/{research-IFMAQWCH.js → research-SW6PLO32.js} +7 -7
- package/dist/{session-BE52OSEV.js → session-6RSOG5NE.js} +11 -11
- package/dist/{trade-YNQVWUYZ.js → trade-45JPCKGP.js} +16 -16
- package/dist/trade-45JPCKGP.js.map +1 -0
- package/dist/{vault-KE5TKCSY.js → vault-GAIOZZPC.js} +8 -8
- package/dist/{xmtp-M2OBCCNR.js → xmtp-A2KIQWGA.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-54WMDJTL.js.map +0 -1
- package/dist/chunk-K2NEFUEP.js.map +0 -1
- package/dist/chunk-TU655ZTV.js.map +0 -1
- package/dist/chunk-UO4UITOY.js.map +0 -1
- package/dist/chunk-VJKZDHH3.js.map +0 -1
- package/dist/cron-QMLRWDJG.js.map +0 -1
- package/dist/trade-YNQVWUYZ.js.map +0 -1
- /package/dist/{abis-OLIDCWDS.js.map → abis-ZQ6I3S6L.js.map} +0 -0
- /package/dist/{addresses-EF5OQSKV.js.map → addresses-MS6BB7AB.js.map} +0 -0
- /package/dist/{agent-VLYILEUP.js.map → agent-I6AUSTZG.js.map} +0 -0
- /package/dist/{chat-ANE3SNHH.js.map → chat-5SI7K5FA.js.map} +0 -0
- /package/dist/{chunk-Z7GRB3OQ.js.map → chunk-4BMAFJKO.js.map} +0 -0
- /package/dist/{chunk-BJ4G3TPP.js.map → chunk-5BYJ3TGZ.js.map} +0 -0
- /package/dist/{chunk-WUYJ7AS6.js.map → chunk-5O3KO7ZI.js.map} +0 -0
- /package/dist/{chunk-QSYLZA4Z.js.map → chunk-7ILOT3SI.js.map} +0 -0
- /package/dist/{chunk-QK3FUTVI.js.map → chunk-I7NXKJCG.js.map} +0 -0
- /package/dist/{chunk-XDWYX5ZM.js.map → chunk-MRUTBOMZ.js.map} +0 -0
- /package/dist/{chunk-RFJSV3EZ.js.map → chunk-UK2G5AZG.js.map} +0 -0
- /package/dist/{client-25LF2O4P.js.map → client-Z7LNEG2F.js.map} +0 -0
- /package/dist/{eas-HHMRO37P.js.map → eas-DWBT332K.js.map} +0 -0
- /package/dist/{governor-AL2XUGBE.js.map → governor-ZVNTHHML.js.map} +0 -0
- /package/dist/{network-R45QDUYO.js.map → network-HCFCNZUI.js.map} +0 -0
- /package/dist/{price-QO22NF5Q.js.map → price-GEUCSTO4.js.map} +0 -0
- /package/dist/{providers-ALMXBRNW.js.map → providers-PWUJ2AR7.js.map} +0 -0
- /package/dist/{research-IFMAQWCH.js.map → research-SW6PLO32.js.map} +0 -0
- /package/dist/{session-BE52OSEV.js.map → session-6RSOG5NE.js.map} +0 -0
- /package/dist/{vault-KE5TKCSY.js.map → vault-GAIOZZPC.js.map} +0 -0
- /package/dist/{xmtp-M2OBCCNR.js.map → xmtp-A2KIQWGA.js.map} +0 -0
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
robinhoodTestnet,
|
|
17
17
|
setNetwork,
|
|
18
18
|
withNetwork
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-ZW2VKCFZ.js";
|
|
20
20
|
import "./chunk-3TZIOAPH.js";
|
|
21
21
|
export {
|
|
22
22
|
CHAIN_REGISTRY,
|
|
@@ -37,4 +37,4 @@ export {
|
|
|
37
37
|
setNetwork,
|
|
38
38
|
withNetwork
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=network-
|
|
40
|
+
//# sourceMappingURL=network-HCFCNZUI.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
quote
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-N5RIB6ZZ.js";
|
|
4
4
|
import {
|
|
5
5
|
SYNTHRA
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-I7TMY7AS.js";
|
|
7
7
|
import {
|
|
8
8
|
getPublicClient
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5BYJ3TGZ.js";
|
|
10
10
|
import {
|
|
11
11
|
getNetwork
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ZW2VKCFZ.js";
|
|
13
13
|
import "./chunk-3TZIOAPH.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-XSP64L7L.js";
|
|
15
15
|
|
|
16
16
|
// src/lib/price.ts
|
|
17
17
|
import { parseUnits, formatUnits } from "viem";
|
|
@@ -133,4 +133,4 @@ export {
|
|
|
133
133
|
getTokenPriceInAsset,
|
|
134
134
|
getTokenPricesInAsset
|
|
135
135
|
};
|
|
136
|
-
//# sourceMappingURL=price-
|
|
136
|
+
//# sourceMappingURL=price-GEUCSTO4.js.map
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
MessariProvider,
|
|
3
3
|
NansenProvider,
|
|
4
4
|
getResearchProvider
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-MRUTBOMZ.js";
|
|
6
|
+
import "./chunk-5BYJ3TGZ.js";
|
|
7
7
|
import {
|
|
8
8
|
robinhoodTestnet
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZW2VKCFZ.js";
|
|
10
10
|
import "./chunk-3TZIOAPH.js";
|
|
11
11
|
|
|
12
12
|
// src/providers/index.ts
|
|
@@ -28,4 +28,4 @@ export {
|
|
|
28
28
|
getResearchProvider,
|
|
29
29
|
listProviders
|
|
30
30
|
};
|
|
31
|
-
//# sourceMappingURL=providers-
|
|
31
|
+
//# sourceMappingURL=providers-PWUJ2AR7.js.map
|
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
MESSARI_COST_ESTIMATE,
|
|
3
3
|
NANSEN_COST_ESTIMATE,
|
|
4
4
|
getResearchProvider
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MRUTBOMZ.js";
|
|
6
6
|
import {
|
|
7
7
|
formatContractError,
|
|
8
8
|
getAccount
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-5BYJ3TGZ.js";
|
|
10
|
+
import "./chunk-ZW2VKCFZ.js";
|
|
11
11
|
import "./chunk-3TZIOAPH.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/research.ts
|
|
@@ -16,7 +16,7 @@ import ora from "ora";
|
|
|
16
16
|
import { confirm } from "@inquirer/prompts";
|
|
17
17
|
import { isAddress } from "viem";
|
|
18
18
|
async function loadXmtp() {
|
|
19
|
-
return import("./xmtp-
|
|
19
|
+
return import("./xmtp-A2KIQWGA.js");
|
|
20
20
|
}
|
|
21
21
|
var COST_ESTIMATES = {
|
|
22
22
|
messari: MESSARI_COST_ESTIMATE,
|
|
@@ -83,7 +83,7 @@ function formatValue(value) {
|
|
|
83
83
|
}
|
|
84
84
|
async function postResearch(fundName, result, prompt) {
|
|
85
85
|
const { pinJSON } = await import("./ipfs-EJ7IHXCU.js");
|
|
86
|
-
const { createResearchAttestation, getEasScanUrl } = await import("./eas-
|
|
86
|
+
const { createResearchAttestation, getEasScanUrl } = await import("./eas-DWBT332K.js");
|
|
87
87
|
const xmtp = await loadXmtp();
|
|
88
88
|
const pinSpinner = ora("Pinning research result to IPFS...").start();
|
|
89
89
|
let resultUri;
|
|
@@ -113,7 +113,7 @@ async function postResearch(fundName, result, prompt) {
|
|
|
113
113
|
let attestationUid;
|
|
114
114
|
try {
|
|
115
115
|
const { getChainContracts } = await import("./config-ZGFS4I7K.js");
|
|
116
|
-
const { getChain } = await import("./network-
|
|
116
|
+
const { getChain } = await import("./network-HCFCNZUI.js");
|
|
117
117
|
const vaultRecipient = getChainContracts(getChain().id).vault;
|
|
118
118
|
const { uid } = await createResearchAttestation(
|
|
119
119
|
result.provider,
|
|
@@ -312,4 +312,4 @@ function registerResearchCommands(program) {
|
|
|
312
312
|
export {
|
|
313
313
|
registerResearchCommands
|
|
314
314
|
};
|
|
315
|
-
//# sourceMappingURL=research-
|
|
315
|
+
//# sourceMappingURL=research-SW6PLO32.js.map
|
|
@@ -9,30 +9,30 @@ import {
|
|
|
9
9
|
getCurrentBlock,
|
|
10
10
|
getGovernorEvents,
|
|
11
11
|
getVaultEvents
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5O3KO7ZI.js";
|
|
13
13
|
import {
|
|
14
14
|
resolveFund
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-I7NXKJCG.js";
|
|
16
16
|
import {
|
|
17
17
|
getGovernorOf
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-ZTR2GPZO.js";
|
|
19
|
+
import "./chunk-I7TMY7AS.js";
|
|
20
20
|
import {
|
|
21
21
|
getPublicClient
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-5BYJ3TGZ.js";
|
|
23
|
+
import "./chunk-ZW2VKCFZ.js";
|
|
24
24
|
import {
|
|
25
25
|
loadConfig
|
|
26
26
|
} from "./chunk-3TZIOAPH.js";
|
|
27
27
|
import {
|
|
28
28
|
SYNDICATE_VAULT_ABI
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-XSP64L7L.js";
|
|
30
30
|
import "./chunk-VR4VHX4D.js";
|
|
31
31
|
|
|
32
32
|
// src/commands/session.ts
|
|
33
33
|
import chalk from "chalk";
|
|
34
34
|
async function loadXmtp() {
|
|
35
|
-
return import("./xmtp-
|
|
35
|
+
return import("./xmtp-A2KIQWGA.js");
|
|
36
36
|
}
|
|
37
37
|
async function resolveGovernor(vaultAddress) {
|
|
38
38
|
const client = getPublicClient();
|
|
@@ -279,8 +279,8 @@ function registerSessionCommands(program) {
|
|
|
279
279
|
}
|
|
280
280
|
);
|
|
281
281
|
session.command("cron <name>").description("Manage participation crons (OpenClaw agents)").option("--remove", "Remove participation crons", false).option("--status", "Show cron status", false).action(async (name, opts) => {
|
|
282
|
-
const { isOpenClaw, registerFundCrons, unregisterFundCrons, getFundCronStatus } = await import("./cron-
|
|
283
|
-
const { isTestnet } = await import("./network-
|
|
282
|
+
const { isOpenClaw, registerFundCrons, unregisterFundCrons, getFundCronStatus } = await import("./cron-E3UAZF5B.js");
|
|
283
|
+
const { isTestnet } = await import("./network-HCFCNZUI.js");
|
|
284
284
|
const { getNotifyTo } = await import("./config-ZGFS4I7K.js");
|
|
285
285
|
if (!isOpenClaw()) {
|
|
286
286
|
console.log(chalk.yellow("Not running on OpenClaw \u2014 cron commands unavailable"));
|
|
@@ -322,4 +322,4 @@ function registerSessionCommands(program) {
|
|
|
322
322
|
export {
|
|
323
323
|
registerSessionCommands
|
|
324
324
|
};
|
|
325
|
-
//# sourceMappingURL=session-
|
|
325
|
+
//# sourceMappingURL=session-6RSOG5NE.js.map
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getResearchProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MRUTBOMZ.js";
|
|
4
4
|
import "./chunk-EGJESQXZ.js";
|
|
5
5
|
import {
|
|
6
6
|
chatCompletion
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7ILOT3SI.js";
|
|
8
8
|
import {
|
|
9
9
|
getQuote
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-N5RIB6ZZ.js";
|
|
11
11
|
import {
|
|
12
12
|
TOKENS
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-I7TMY7AS.js";
|
|
14
14
|
import {
|
|
15
15
|
formatContractError,
|
|
16
16
|
getAccount,
|
|
17
17
|
getPublicClient,
|
|
18
18
|
sendTxWithRetry,
|
|
19
19
|
waitForReceipt
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-5BYJ3TGZ.js";
|
|
21
21
|
import {
|
|
22
22
|
getChain,
|
|
23
23
|
getExplorerUrl,
|
|
24
24
|
getNetwork
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-ZW2VKCFZ.js";
|
|
26
26
|
import {
|
|
27
27
|
getUniswapApiKey,
|
|
28
28
|
loadConfig,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
} from "./chunk-3TZIOAPH.js";
|
|
31
31
|
import {
|
|
32
32
|
ERC20_ABI
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-XSP64L7L.js";
|
|
34
34
|
|
|
35
35
|
// src/commands/trade.ts
|
|
36
36
|
import chalk from "chalk";
|
|
@@ -555,7 +555,7 @@ async function getCurrentPrice(tokenAddress, tokenDecimals, feeTier) {
|
|
|
555
555
|
// src/commands/trade.ts
|
|
556
556
|
var uniswap = new UniswapProvider();
|
|
557
557
|
async function loadXmtp() {
|
|
558
|
-
return import("./xmtp-
|
|
558
|
+
return import("./xmtp-A2KIQWGA.js");
|
|
559
559
|
}
|
|
560
560
|
var ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
561
561
|
var KNOWN_MEMECOINS = {
|
|
@@ -661,7 +661,7 @@ function registerTradeCommands(program) {
|
|
|
661
661
|
console.error(chalk.red(`trade commands are not supported on ${network}.`));
|
|
662
662
|
console.error(
|
|
663
663
|
chalk.dim(
|
|
664
|
-
"They require the Uniswap Trading API, which covers Base only. Sherwood
|
|
664
|
+
"They require the Uniswap Trading API, which covers Base only. Sherwood deploys on Robinhood Chain \u2014 the mainnet fork (chain 9994663, the default) and the L2 testnet (chain 46630)."
|
|
665
665
|
)
|
|
666
666
|
);
|
|
667
667
|
process.exit(1);
|
|
@@ -752,7 +752,7 @@ function registerTradeCommands(program) {
|
|
|
752
752
|
}
|
|
753
753
|
const wrapSpinner = ora("Wrapping ETH \u2192 WETH...").start();
|
|
754
754
|
try {
|
|
755
|
-
const { writeContractWithRetry: writeContractWithRetry2, waitForReceipt: waitForReceiptFn } = await import("./client-
|
|
755
|
+
const { writeContractWithRetry: writeContractWithRetry2, waitForReceipt: waitForReceiptFn } = await import("./client-Z7LNEG2F.js");
|
|
756
756
|
const wethAddr = TOKENS().WETH;
|
|
757
757
|
const wrapHash = await writeContractWithRetry2({
|
|
758
758
|
address: wethAddr,
|
|
@@ -761,7 +761,7 @@ function registerTradeCommands(program) {
|
|
|
761
761
|
args: [],
|
|
762
762
|
value: inputAmount,
|
|
763
763
|
account,
|
|
764
|
-
chain: (await import("./network-
|
|
764
|
+
chain: (await import("./network-HCFCNZUI.js")).getChain()
|
|
765
765
|
});
|
|
766
766
|
await waitForReceiptFn(wrapHash);
|
|
767
767
|
wrapSpinner.succeed(`Wrapped ${opts.amount} ETH \u2192 WETH`);
|
|
@@ -875,9 +875,9 @@ function registerTradeCommands(program) {
|
|
|
875
875
|
}
|
|
876
876
|
console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash))}`);
|
|
877
877
|
try {
|
|
878
|
-
const { createTradeAttestation, getEasScanUrl } = await import("./eas-
|
|
878
|
+
const { createTradeAttestation, getEasScanUrl } = await import("./eas-DWBT332K.js");
|
|
879
879
|
const { getChainContracts } = await import("./config-ZGFS4I7K.js");
|
|
880
|
-
const { getChain: getActiveChain } = await import("./network-
|
|
880
|
+
const { getChain: getActiveChain } = await import("./network-HCFCNZUI.js");
|
|
881
881
|
const vaultRecipient = getChainContracts(getActiveChain().id).vault;
|
|
882
882
|
const { uid } = await createTradeAttestation(
|
|
883
883
|
inputAddr,
|
|
@@ -1003,9 +1003,9 @@ function registerTradeCommands(program) {
|
|
|
1003
1003
|
}
|
|
1004
1004
|
console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash))}`);
|
|
1005
1005
|
try {
|
|
1006
|
-
const { createTradeAttestation, getEasScanUrl } = await import("./eas-
|
|
1006
|
+
const { createTradeAttestation, getEasScanUrl } = await import("./eas-DWBT332K.js");
|
|
1007
1007
|
const { getChainContracts } = await import("./config-ZGFS4I7K.js");
|
|
1008
|
-
const { getChain: getActiveChain } = await import("./network-
|
|
1008
|
+
const { getChain: getActiveChain } = await import("./network-HCFCNZUI.js");
|
|
1009
1009
|
const vaultRecipient = getChainContracts(getActiveChain().id).vault;
|
|
1010
1010
|
const { uid } = await createTradeAttestation(
|
|
1011
1011
|
tokenAddr,
|
|
@@ -1180,4 +1180,4 @@ function sleep(ms) {
|
|
|
1180
1180
|
export {
|
|
1181
1181
|
registerTradeCommands
|
|
1182
1182
|
};
|
|
1183
|
-
//# sourceMappingURL=trade-
|
|
1183
|
+
//# sourceMappingURL=trade-45JPCKGP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/trade.ts","../src/providers/uniswap.ts","../src/lib/signals.ts","../src/lib/exit-strategy.ts","../src/lib/positions.ts"],"sourcesContent":["/**\n * Trade commands — sherwood trade <subcommand>\n *\n * Memecoin trading via the Uniswap Trading API on Base, driven by signal-based\n * analysis (on-chain flows, social sentiment, fundamentals).\n *\n * Trades execute from the agent's own EOA wallet using USDC as quote currency.\n * Requires a Uniswap API key: `sherwood config set --uniswap-api-key <key>`\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { confirm } from \"@inquirer/prompts\";\nimport type { Address } from \"viem\";\nimport { isAddress, parseUnits, formatUnits } from \"viem\";\n\nimport { getPublicClient, getAccount, formatContractError } from \"../lib/client.js\";\nimport { getExplorerUrl, getNetwork } from \"../lib/network.js\";\nimport { TOKENS } from \"../lib/addresses.js\";\nimport { ERC20_ABI } from \"../lib/abis.js\";\nimport { UniswapProvider } from \"../providers/uniswap.js\";\nimport { analyzeToken } from \"../lib/signals.js\";\nimport type { SignalResult } from \"../lib/signals.js\";\nimport { checkExit, DEFAULT_EXIT_CONFIG } from \"../lib/exit-strategy.js\";\nimport type { ExitConfig } from \"../lib/exit-strategy.js\";\nimport {\n getOpenPositions,\n addPosition,\n closePosition,\n updateHighWater,\n getCurrentPrice,\n} from \"../lib/positions.js\";\nimport type { MessageType } from \"../lib/types.js\";\n\nconst uniswap = new UniswapProvider();\n\n// Lazy-load XMTP to avoid breaking non-chat environments\nasync function loadXmtp() {\n return import(\"../lib/xmtp.js\");\n}\n\n// ── Token resolution ──\n\nconst ETH_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\n\nconst KNOWN_MEMECOINS: Record<string, Address> = {\n DEGEN: \"0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed\" as Address,\n TOSHI: \"0xAC1Bd2486aAf3B5C0fc3Fd868558b082a531B2B4\" as Address,\n BRETT: \"0x532f27101965dd16442E59d40670FaF5eBB142E4\" as Address,\n HIGHER: \"0x0578d8A44db98B23BF096A382e016e29a5Ce0ffe\" as Address,\n};\n\nconst WETH_ABI = [\n {\n name: \"deposit\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [],\n outputs: [],\n },\n] as const;\n\nasync function resolveToken(\n symbolOrAddress: string,\n): Promise<{ address: Address; symbol: string; decimals: number }> {\n const upper = symbolOrAddress.toUpperCase();\n\n // ETH is native — not an ERC-20, handle specially\n if (upper === \"ETH\") {\n return { address: ETH_ADDRESS, symbol: \"ETH\", decimals: 18 };\n }\n\n let address: Address;\n let symbol: string;\n\n if (isAddress(symbolOrAddress)) {\n address = symbolOrAddress as Address;\n const client = getPublicClient();\n try {\n symbol = (await client.readContract({\n address,\n abi: ERC20_ABI,\n functionName: \"symbol\",\n })) as string;\n } catch {\n symbol = address.slice(0, 8);\n }\n } else {\n const tokens = TOKENS();\n const tokenMap: Record<string, Address> = {\n USDC: tokens.USDC,\n WETH: tokens.WETH,\n ...KNOWN_MEMECOINS,\n };\n address = tokenMap[upper];\n if (!address) {\n throw new Error(\n `Unknown token: ${symbolOrAddress}. Use a contract address or known symbol (${Object.keys(tokenMap).join(\", \")}).`,\n );\n }\n symbol = upper;\n }\n\n const client = getPublicClient();\n const decimals = (await client.readContract({\n address,\n abi: ERC20_ABI,\n functionName: \"decimals\",\n })) as number;\n\n return { address, symbol, decimals };\n}\n\n// ── Chat posting ──\n\nasync function postToChat(\n fund: string,\n type: MessageType,\n text: string,\n data: Record<string, unknown>,\n): Promise<void> {\n try {\n const xmtp = await loadXmtp();\n const group = await xmtp.getGroup(\"\", fund);\n await xmtp.sendEnvelope(group, {\n type,\n from: getAccount().address,\n text,\n data,\n timestamp: Math.floor(Date.now() / 1000),\n });\n } catch {\n // Chat posting is best-effort\n }\n}\n\n// ── Formatting ──\n\nfunction formatSignalTable(results: { symbol: string; address: Address; result: SignalResult }[]): void {\n console.log();\n console.log(chalk.bold(\" Token Score Action Conf. On-chain Social Fundmtl\"));\n console.log(chalk.dim(\" \" + \"─\".repeat(72)));\n\n for (const { symbol, address, result } of results) {\n const scoreColor = result.compositeScore > 0 ? chalk.green : result.compositeScore < 0 ? chalk.red : chalk.dim;\n const actionColor =\n result.action === \"buy\" ? chalk.green.bold :\n result.action === \"sell\" ? chalk.red.bold :\n chalk.dim;\n\n const onChain = result.signals.find((s) => s.source === \"onchain\");\n const social = result.signals.find((s) => s.source === \"social\");\n const fundamental = result.signals.find((s) => s.source === \"fundamental\");\n\n const shortAddr = `${address.slice(0, 6)}..`;\n const label = `${symbol.padEnd(6)} (${shortAddr})`;\n\n console.log(\n ` ${label.padEnd(16)} ` +\n `${scoreColor(result.compositeScore.toFixed(2).padStart(6))} ` +\n `${actionColor(result.action.toUpperCase().padEnd(6))} ` +\n `${(result.confidence * 100).toFixed(0).padStart(4)}% ` +\n `${formatSignalValue(onChain?.value).padStart(8)} ` +\n `${formatSignalValue(social?.value).padStart(6)} ` +\n `${formatSignalValue(fundamental?.value).padStart(7)}`,\n );\n }\n console.log();\n}\n\nfunction formatSignalValue(v: number | undefined): string {\n if (v === undefined) return chalk.dim(\"n/a\");\n const s = (v >= 0 ? \"+\" : \"\") + v.toFixed(2);\n return v > 0 ? chalk.green(s) : v < 0 ? chalk.red(s) : chalk.dim(s);\n}\n\n// ── Commands ──\n\n// The Uniswap Trading API (and the KNOWN_MEMECOINS universe) covers Base only.\n// No currently registered network qualifies — Sherwood currently deploys on\n// Robinhood testnet (chain 46630) — so every trade subcommand fails fast\n// instead of advertising a capability that would throw mid-flow.\nconst TRADING_API_NETWORKS = new Set<string>([\"base\", \"base-sepolia\"]);\n\nexport function registerTradeCommands(program: Command): void {\n const trade = program\n .command(\"trade\")\n .description(\"Memecoin trading — scan, buy, sell, monitor positions (Uniswap Trading API on Base)\");\n\n trade.hook(\"preAction\", () => {\n const network = getNetwork();\n if (!TRADING_API_NETWORKS.has(network)) {\n console.error(chalk.red(`trade commands are not supported on ${network}.`));\n console.error(\n chalk.dim(\n \"They require the Uniswap Trading API, which covers Base only. \" +\n \"Sherwood deploys on Robinhood Chain — the mainnet fork (chain \" +\n \"9994663, the default) and the L2 testnet (chain 46630).\",\n ),\n );\n process.exit(1);\n }\n });\n\n // ── trade scan ──\n\n trade\n .command(\"scan\")\n .description(\"Analyze token(s) using on-chain, social, and fundamental signals\")\n .option(\"--token <addr|symbol>\", \"Specific token to analyze (otherwise scans known memecoins)\")\n .option(\"--fund <name>\", \"Post results to fund chat\")\n .option(\"--yes\", \"Skip cost confirmation\", false)\n .action(async (opts: { token?: string; fund?: string; yes: boolean }) => {\n const targets: { symbol: string; address: Address }[] = [];\n\n if (opts.token) {\n const resolved = await resolveToken(opts.token);\n targets.push({ symbol: resolved.symbol, address: resolved.address });\n } else {\n for (const [symbol, address] of Object.entries(KNOWN_MEMECOINS)) {\n targets.push({ symbol, address });\n }\n }\n\n const estCost = targets.length * 0.26;\n console.log();\n console.log(chalk.bold(\"Memecoin Alpha Scan\"));\n console.log(chalk.dim(\"─\".repeat(40)));\n console.log(` Tokens: ${targets.map((t) => t.symbol).join(\", \")}`);\n console.log(` Est. cost: ${chalk.yellow(`~$${estCost.toFixed(2)} USDC`)} (x402 research) + Venice inference`);\n console.log();\n\n if (!opts.yes) {\n const ok = await confirm({\n message: `Proceed with signal analysis?`,\n default: true,\n });\n if (!ok) {\n console.log(chalk.dim(\"Cancelled.\"));\n return;\n }\n }\n\n const spinner = ora(\"Analyzing signals...\").start();\n const results: { symbol: string; address: Address; result: SignalResult }[] = [];\n\n for (const target of targets) {\n try {\n spinner.text = `Analyzing ${target.symbol}...`;\n const result = await analyzeToken(target.address, target.symbol);\n results.push({ ...target, result });\n } catch {\n results.push({\n ...target,\n result: {\n action: \"hold\",\n confidence: 0,\n compositeScore: 0,\n signals: [],\n costUsdc: \"0\",\n timestamp: Math.floor(Date.now() / 1000),\n },\n });\n }\n }\n\n spinner.succeed(\"Scan complete\");\n formatSignalTable(results);\n\n const totalCost = results.reduce((sum, r) => sum + Number(r.result.costUsdc), 0);\n console.log(chalk.dim(` Total research cost: $${totalCost.toFixed(4)} USDC`));\n console.log();\n\n if (opts.fund) {\n await postToChat(opts.fund, \"TRADE_SIGNAL\" as MessageType,\n `Scanned ${results.length} tokens: ${results.filter((r) => r.result.action === \"buy\").map((r) => r.symbol).join(\", \") || \"no buys\"}`,\n { results: results.map((r) => ({ symbol: r.symbol, action: r.result.action, score: r.result.compositeScore })) },\n );\n }\n });\n\n // ── trade buy ──\n\n trade\n .command(\"buy\")\n .description(\"Buy a token via Uniswap Trading API\")\n .requiredOption(\"--token <addr|symbol>\", \"Token to buy\")\n .requiredOption(\"--amount <n>\", \"Amount of input token to spend\")\n .option(\"--with <token>\", \"Input token to spend (default: USDC). Use ETH for native ETH (auto-wraps to WETH).\", \"USDC\")\n .option(\"--slippage <pct>\", \"Slippage tolerance % (default: 0.5)\", \"0.5\")\n .option(\"--stop-loss <pct>\", \"Stop loss percentage (default: 10)\", \"10\")\n .option(\"--trailing-stop <pct>\", \"Trailing stop percentage (0 = disabled)\", \"0\")\n .option(\"--deadline <hours>\", \"Force exit after N hours (0 = none)\", \"0\")\n .option(\"--fund <name>\", \"Post trade to fund chat\")\n .action(async (opts) => {\n const { address: tokenAddr, symbol, decimals } = await resolveToken(opts.token as string);\n const slippage = Number(opts.slippage);\n\n // Resolve input token\n const inputSpec = (opts.with as string).toUpperCase();\n const isEthInput = inputSpec === \"ETH\";\n // ETH input: wrap to WETH first, then swap WETH → target\n const {\n address: inputAddr,\n symbol: inputSymbol,\n decimals: inputDecimals,\n } = isEthInput\n ? { address: TOKENS().WETH, symbol: \"ETH\", decimals: 18 }\n : await resolveToken(opts.with as string);\n const inputAmount = parseUnits(opts.amount as string, inputDecimals);\n\n // Check balance\n const client = getPublicClient();\n const account = getAccount();\n\n if (isEthInput) {\n const ethBalance = await client.getBalance({ address: account.address });\n if (ethBalance < inputAmount) {\n console.error(chalk.red(\n `Insufficient ETH. Have ${formatUnits(ethBalance, 18)}, need ${opts.amount}`,\n ));\n process.exit(1);\n }\n\n // Wrap ETH → WETH\n const wrapSpinner = ora(\"Wrapping ETH → WETH...\").start();\n try {\n const { writeContractWithRetry, waitForReceipt: waitForReceiptFn } = await import(\"../lib/client.js\");\n const wethAddr = TOKENS().WETH;\n const wrapHash = await writeContractWithRetry({\n address: wethAddr,\n abi: WETH_ABI,\n functionName: \"deposit\",\n args: [],\n value: inputAmount,\n account,\n chain: (await import(\"../lib/network.js\")).getChain(),\n });\n await waitForReceiptFn(wrapHash);\n wrapSpinner.succeed(`Wrapped ${opts.amount} ETH → WETH`);\n } catch (err) {\n wrapSpinner.fail(\"ETH wrap failed\");\n console.error(chalk.red(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n } else {\n const balance = (await client.readContract({\n address: inputAddr,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account.address],\n })) as bigint;\n\n if (balance < inputAmount) {\n console.error(chalk.red(\n `Insufficient ${inputSymbol}. Have ${formatUnits(balance, inputDecimals)}, need ${opts.amount}`,\n ));\n process.exit(1);\n }\n }\n\n // Get quote via Uniswap Trading API (handles routing automatically)\n const quoteSpinner = ora(\"Getting quote from Uniswap API...\").start();\n let expectedOut: bigint;\n\n try {\n const result = await uniswap.fullQuote({\n tokenIn: inputAddr,\n tokenOut: tokenAddr,\n amountIn: inputAmount,\n slippageTolerance: slippage,\n });\n expectedOut = result.amountOut;\n const routing = result.routing;\n quoteSpinner.succeed(\n `Quote: ${formatUnits(result.amountOut, decimals)} ${symbol} (${routing} route)`,\n );\n } catch (err) {\n quoteSpinner.fail(\"Quote failed\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n\n // Execute swap via Uniswap Trading API (check_approval + quote + swap + sign + broadcast)\n const swapSpinner = ora(\"Executing swap via Uniswap API...\").start();\n let txHash: string;\n try {\n const result = await uniswap.swap({\n tokenIn: inputAddr,\n tokenOut: tokenAddr,\n amountIn: inputAmount,\n amountOutMinimum: 0n, // slippage handled by API\n fee: 3000,\n slippageTolerance: slippage,\n });\n txHash = result.hash;\n\n if (!result.success) {\n swapSpinner.fail(\"Swap reverted\");\n console.error(chalk.dim(` Tx: ${getExplorerUrl(result.hash)}`));\n process.exit(1);\n }\n swapSpinner.succeed(\"Swap executed\");\n } catch (err) {\n swapSpinner.fail(\"Swap failed\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n\n // Read actual token balance received\n const tokenBalance = (await client.readContract({\n address: tokenAddr,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account.address],\n })) as bigint;\n\n const tokensReceived = tokenBalance > 0n ? tokenBalance : expectedOut;\n const entryPrice = Number(opts.amount) / Number(formatUnits(tokensReceived, decimals));\n\n // Build exit config\n const exitConfig: ExitConfig = {\n stopLossPct: Number(opts.stopLoss) || DEFAULT_EXIT_CONFIG.stopLossPct,\n trailingStopPct: Number(opts.trailingStop) || DEFAULT_EXIT_CONFIG.trailingStopPct,\n takeProfitPct: DEFAULT_EXIT_CONFIG.takeProfitPct,\n deadlineUnix: Number(opts.deadline) > 0\n ? Math.floor(Date.now() / 1000) + Number(opts.deadline) * 3600\n : 0,\n signalExitEnabled: true,\n };\n\n // Save position\n addPosition({\n tokenAddress: tokenAddr,\n tokenSymbol: symbol,\n tokenDecimals: decimals,\n amountIn: opts.amount as string,\n amountOut: tokensReceived.toString(),\n entryPrice,\n highWaterPrice: entryPrice,\n feeTier: 3000, // stored for price lookups via QuoterV2\n openedAt: Math.floor(Date.now() / 1000),\n txHash,\n exitConfig,\n inputTokenAddress: inputAddr,\n inputTokenSymbol: inputSymbol,\n inputTokenDecimals: inputDecimals,\n });\n\n console.log();\n console.log(chalk.bold(\"Trade Executed\"));\n console.log(chalk.dim(\"─\".repeat(40)));\n console.log(` Token: ${symbol} (${tokenAddr})`);\n console.log(` Spent: ${opts.amount} ${inputSymbol}`);\n console.log(` Received: ${formatUnits(tokensReceived, decimals)} ${symbol}`);\n console.log(` Entry: ${entryPrice.toFixed(8)} ${inputSymbol}/${symbol}`);\n console.log(` Stop: -${exitConfig.stopLossPct}%`);\n if (exitConfig.trailingStopPct > 0) {\n console.log(` Trailing: ${exitConfig.trailingStopPct}%`);\n }\n if (exitConfig.deadlineUnix > 0) {\n console.log(` Deadline: ${new Date(exitConfig.deadlineUnix * 1000).toISOString()}`);\n }\n console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash as `0x${string}`))}`);\n\n // EAS attestation (best-effort) — recipient is vault so dashboard can display it\n try {\n const { createTradeAttestation, getEasScanUrl } = await import(\"../lib/eas.js\");\n const { getChainContracts } = await import(\"../lib/config.js\");\n const { getChain: getActiveChain } = await import(\"../lib/network.js\");\n const vaultRecipient = getChainContracts(getActiveChain().id).vault as `0x${string}` | undefined;\n const { uid } = await createTradeAttestation(\n inputAddr, tokenAddr, inputAmount,\n formatUnits(tokensReceived, decimals),\n txHash, \"BUY\", vaultRecipient,\n );\n if (uid !== \"0x0000000000000000000000000000000000000000000000000000000000000000\") {\n console.log(` Attested: ${chalk.dim(getEasScanUrl(uid))}`);\n }\n } catch {\n // Attestation is best-effort\n }\n\n console.log();\n\n if (opts.fund) {\n await postToChat(opts.fund, \"TRADE_EXECUTED\" as MessageType,\n `Bought ${formatUnits(tokensReceived, decimals)} ${symbol} for ${opts.amount} ${inputSymbol} via Uniswap`,\n { token: symbol, address: tokenAddr, amountIn: opts.amount, inputToken: inputSymbol, txHash },\n );\n }\n });\n\n // ── trade sell ──\n\n trade\n .command(\"sell\")\n .description(\"Sell a token position via Uniswap Trading API\")\n .requiredOption(\"--token <addr|symbol>\", \"Token to sell\")\n .option(\"--amount <n>\", \"Token amount to sell (default: entire position)\")\n .option(\"--for <token>\", \"Output token to receive (default: USDC)\", \"USDC\")\n .option(\"--slippage <pct>\", \"Slippage tolerance % (default: 0.5)\", \"0.5\")\n .option(\"--fund <name>\", \"Post trade to fund chat\")\n .action(async (opts) => {\n const { address: tokenAddr, symbol, decimals } = await resolveToken(opts.token as string);\n const {\n address: outputAddr,\n symbol: outputSymbol,\n decimals: outputDecimals,\n } = await resolveToken(opts.for as string);\n const slippage = Number(opts.slippage);\n\n // Find open position\n const positions = getOpenPositions();\n const pos = positions.find(\n (p) => p.tokenAddress.toLowerCase() === tokenAddr.toLowerCase(),\n );\n\n // Determine sell amount\n const client = getPublicClient();\n const account = getAccount();\n let sellAmount: bigint;\n\n if (opts.amount) {\n sellAmount = parseUnits(opts.amount as string, decimals);\n } else {\n sellAmount = (await client.readContract({\n address: tokenAddr,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account.address],\n })) as bigint;\n }\n\n if (sellAmount === 0n) {\n console.error(chalk.red(\"No tokens to sell.\"));\n process.exit(1);\n }\n\n // Quote via Uniswap Trading API\n const quoteSpinner = ora(\"Getting quote from Uniswap API...\").start();\n let expectedOut: bigint;\n\n try {\n const result = await uniswap.fullQuote({\n tokenIn: tokenAddr,\n tokenOut: outputAddr,\n amountIn: sellAmount,\n slippageTolerance: slippage,\n });\n expectedOut = result.amountOut;\n const routing = result.routing;\n quoteSpinner.succeed(\n `Quote: ${formatUnits(result.amountOut, outputDecimals)} ${outputSymbol} (${routing} route)`,\n );\n } catch (err) {\n quoteSpinner.fail(\"Quote failed\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n\n // Execute sell via Uniswap Trading API\n const swapSpinner = ora(\"Executing sell via Uniswap API...\").start();\n let txHash: string;\n try {\n const result = await uniswap.swap({\n tokenIn: tokenAddr,\n tokenOut: outputAddr,\n amountIn: sellAmount,\n amountOutMinimum: 0n,\n fee: 3000,\n slippageTolerance: slippage,\n });\n txHash = result.hash;\n\n if (!result.success) {\n swapSpinner.fail(\"Sell reverted\");\n process.exit(1);\n }\n swapSpinner.succeed(\"Sell executed\");\n } catch (err) {\n swapSpinner.fail(\"Sell failed\");\n console.error(chalk.red(formatContractError(err)));\n process.exit(1);\n }\n\n // Calculate P&L (meaningful when output matches the original input token)\n const outputReceived = Number(formatUnits(expectedOut, outputDecimals));\n const costBasis = pos ? Number(pos.amountIn) : 0;\n const inputMatchesOutput = pos\n ? (pos.inputTokenSymbol ?? \"USDC\").toUpperCase() === outputSymbol.toUpperCase()\n : outputSymbol.toUpperCase() === \"USDC\";\n const pnl = costBasis > 0 && inputMatchesOutput ? outputReceived - costBasis : 0;\n const pnlPct = costBasis > 0 && inputMatchesOutput ? (pnl / costBasis) * 100 : 0;\n const exitPrice = sellAmount > 0n\n ? outputReceived / Number(formatUnits(sellAmount, decimals))\n : 0;\n\n if (pos) {\n closePosition(tokenAddr, {\n exitPrice,\n closedAt: Math.floor(Date.now() / 1000),\n exitTxHash: txHash,\n exitReason: \"manual\",\n pnlUsdc: pnl,\n pnlPct,\n });\n }\n\n const pnlColor = pnl >= 0 ? chalk.green : chalk.red;\n\n console.log();\n console.log(chalk.bold(\"Position Closed\"));\n console.log(chalk.dim(\"─\".repeat(40)));\n console.log(` Token: ${symbol}`);\n console.log(` Sold: ${formatUnits(sellAmount, decimals)} ${symbol}`);\n console.log(` Received: ~${outputReceived.toFixed(outputDecimals <= 6 ? 2 : 6)} ${outputSymbol}`);\n if (costBasis > 0 && inputMatchesOutput) {\n const posInputSymbol = pos?.inputTokenSymbol ?? \"USDC\";\n console.log(` Cost: ${costBasis.toFixed(2)} ${posInputSymbol}`);\n console.log(` P&L: ${pnlColor(`${pnl >= 0 ? \"+\" : \"\"}${pnl.toFixed(2)} ${outputSymbol} (${pnlPct >= 0 ? \"+\" : \"\"}${pnlPct.toFixed(1)}%)`)}`);\n }\n console.log(` Tx: ${chalk.dim(getExplorerUrl(txHash as `0x${string}`))}`);\n\n // EAS attestation (best-effort) — recipient is vault so dashboard can display it\n try {\n const { createTradeAttestation, getEasScanUrl } = await import(\"../lib/eas.js\");\n const { getChainContracts } = await import(\"../lib/config.js\");\n const { getChain: getActiveChain } = await import(\"../lib/network.js\");\n const vaultRecipient = getChainContracts(getActiveChain().id).vault as `0x${string}` | undefined;\n const { uid } = await createTradeAttestation(\n tokenAddr, outputAddr, sellAmount,\n formatUnits(expectedOut, outputDecimals),\n txHash, \"SELL\", vaultRecipient,\n );\n if (uid !== \"0x0000000000000000000000000000000000000000000000000000000000000000\") {\n console.log(` Attested: ${chalk.dim(getEasScanUrl(uid))}`);\n }\n } catch {\n // Attestation is best-effort\n }\n\n console.log();\n\n if (opts.fund) {\n await postToChat(opts.fund, \"TRADE_EXECUTED\" as MessageType,\n `Sold ${formatUnits(sellAmount, decimals)} ${symbol} for ~${outputReceived.toFixed(2)} ${outputSymbol}${inputMatchesOutput && costBasis > 0 ? ` (P&L: ${pnl >= 0 ? \"+\" : \"\"}${pnl.toFixed(2)})` : \"\"}`,\n { token: symbol, address: tokenAddr, outputReceived, outputToken: outputSymbol, pnl, pnlPct, txHash },\n );\n }\n });\n\n // ── trade positions ──\n\n trade\n .command(\"positions\")\n .description(\"Show open positions with current prices and unrealized P&L\")\n .action(async () => {\n const positions = getOpenPositions();\n if (positions.length === 0) {\n console.log(chalk.dim(\"\\n No open positions.\\n\"));\n return;\n }\n\n console.log();\n console.log(chalk.bold(\"Open Positions\"));\n console.log(chalk.dim(\"─\".repeat(80)));\n console.log(chalk.dim(\n \" Token Entry Current Qty Cost Value P&L\",\n ));\n\n for (const pos of positions) {\n try {\n const current = await getCurrentPrice(pos.tokenAddress, pos.tokenDecimals, pos.feeTier);\n const qty = Number(formatUnits(BigInt(pos.amountOut), pos.tokenDecimals));\n const cost = Number(pos.amountIn);\n const value = qty * current;\n const pnl = value - cost;\n const pnlPct = cost > 0 ? (pnl / cost) * 100 : 0;\n const pnlColor = pnl >= 0 ? chalk.green : chalk.red;\n\n console.log(\n ` ${pos.tokenSymbol.padEnd(14)} ` +\n `$${pos.entryPrice.toFixed(6).padStart(10)} ` +\n `$${current.toFixed(6).padStart(10)} ` +\n `${qty.toFixed(2).padStart(15)} ` +\n `$${cost.toFixed(2).padStart(8)} ` +\n `$${value.toFixed(2).padStart(8)} ` +\n pnlColor(`${pnl >= 0 ? \"+\" : \"\"}${pnl.toFixed(2)} (${pnlPct >= 0 ? \"+\" : \"\"}${pnlPct.toFixed(1)}%)`),\n );\n\n if (current > pos.highWaterPrice) {\n updateHighWater(pos.tokenAddress, current);\n }\n } catch {\n console.log(\n ` ${pos.tokenSymbol.padEnd(14)} ` +\n `$${pos.entryPrice.toFixed(6).padStart(10)} ` +\n `${chalk.dim(\"price unavailable\")}`,\n );\n }\n }\n console.log();\n });\n\n // ── trade monitor ──\n\n trade\n .command(\"monitor\")\n .description(\"Monitor positions and auto-exit on signal triggers\")\n .option(\"--interval <seconds>\", \"Check interval in seconds (default: 300)\", \"300\")\n .option(\"--fund <name>\", \"Post updates to fund chat\")\n .action(async (opts) => {\n const interval = Number(opts.interval) * 1000;\n\n console.log();\n console.log(chalk.bold(\"Position Monitor\"));\n console.log(chalk.dim(`Checking every ${opts.interval}s. Press Ctrl-C to stop.`));\n console.log();\n\n const running = { value: true };\n process.on(\"SIGINT\", () => {\n running.value = false;\n console.log(chalk.dim(\"\\nStopping monitor...\"));\n });\n\n while (running.value) {\n const positions = getOpenPositions();\n if (positions.length === 0) {\n console.log(chalk.dim(\" No open positions. Waiting...\"));\n await sleep(interval);\n continue;\n }\n\n for (const pos of positions) {\n if (!running.value) break;\n\n try {\n const current = await getCurrentPrice(pos.tokenAddress, pos.tokenDecimals, pos.feeTier);\n const hwPrice = Math.max(current, pos.highWaterPrice);\n if (current > pos.highWaterPrice) {\n updateHighWater(pos.tokenAddress, current);\n }\n\n // Run signal analysis for exit check\n let signalResult: SignalResult | undefined;\n if (pos.exitConfig.signalExitEnabled) {\n try {\n signalResult = await analyzeToken(pos.tokenAddress, pos.tokenSymbol);\n } catch {\n // Signal analysis can fail — continue with price-only checks\n }\n }\n\n const exit = checkExit(pos.entryPrice, current, hwPrice, pos.exitConfig, signalResult);\n const pnlPct = exit.currentPnlPct;\n const pnlColor = pnlPct >= 0 ? chalk.green : chalk.red;\n const ts = new Date().toLocaleTimeString();\n\n console.log(\n ` [${ts}] ${pos.tokenSymbol}: ` +\n `$${current.toFixed(6)} ` +\n pnlColor(`(${pnlPct >= 0 ? \"+\" : \"\"}${pnlPct.toFixed(1)}%)`) +\n (exit.shouldExit ? chalk.red.bold(` → EXIT (${exit.reason})`) : \"\"),\n );\n\n if (exit.shouldExit) {\n console.log(chalk.yellow(` Executing exit for ${pos.tokenSymbol}: ${exit.reason}`));\n\n if (opts.fund) {\n await postToChat(opts.fund, \"RISK_ALERT\" as MessageType,\n `Exit triggered for ${pos.tokenSymbol}: ${exit.reason} (${pnlPct >= 0 ? \"+\" : \"\"}${pnlPct.toFixed(1)}%)`,\n { token: pos.tokenSymbol, reason: exit.reason, pnlPct },\n );\n }\n\n try {\n const sellAmount = BigInt(pos.amountOut);\n const usdc = TOKENS().USDC;\n\n // Get quote for P&L calculation\n const { amountOut: sellQuote } = await uniswap.fullQuote({\n tokenIn: pos.tokenAddress,\n tokenOut: usdc,\n amountIn: sellAmount,\n slippageTolerance: 0.5,\n });\n\n // Execute sell via Trading API\n const result = await uniswap.swap({\n tokenIn: pos.tokenAddress,\n tokenOut: usdc,\n amountIn: sellAmount,\n amountOutMinimum: 0n,\n fee: 3000,\n slippageTolerance: 1.0, // 1% for auto-sell\n });\n\n const usdcReceived = Number(formatUnits(sellQuote, 6));\n const costBasis = Number(pos.amountIn);\n const pnlUsdc = usdcReceived - costBasis;\n\n closePosition(pos.tokenAddress, {\n exitPrice: current,\n closedAt: Math.floor(Date.now() / 1000),\n exitTxHash: result.hash,\n exitReason: exit.reason,\n pnlUsdc,\n pnlPct,\n });\n\n const pnlStr = `${pnlUsdc >= 0 ? \"+\" : \"\"}${pnlUsdc.toFixed(2)} USDC`;\n console.log(chalk.green(` Sold ${pos.tokenSymbol}: ${pnlStr}`));\n\n if (opts.fund) {\n await postToChat(opts.fund, \"TRADE_EXECUTED\" as MessageType,\n `Auto-sold ${pos.tokenSymbol}: ${pnlStr} (${exit.reason})`,\n { token: pos.tokenSymbol, reason: exit.reason, pnlUsdc, pnlPct, txHash: result.hash },\n );\n }\n } catch (err) {\n console.error(chalk.red(\n ` Failed to sell ${pos.tokenSymbol}: ${formatContractError(err)}`,\n ));\n }\n }\n } catch {\n console.error(chalk.dim(\n ` [${new Date().toLocaleTimeString()}] ${pos.tokenSymbol}: price check failed`,\n ));\n }\n }\n\n if (running.value) {\n await sleep(interval);\n }\n }\n\n console.log(chalk.dim(\"Monitor stopped.\"));\n });\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * PARKED — Base-only Uniswap Trading API adapter (inactive on the current\n * deployment target).\n *\n * The hosted Trading API covers Base / Base Sepolia only; the CLI's sole\n * registered chain is Robinhood testnet (chain 46630), so this adapter cannot\n * execute there and is NOT advertised by `sherwood providers` (see\n * providers/index.ts). Its only consumer is `sherwood trade`, which fails fast\n * on unsupported networks (commands/trade.ts). Swaps on the live chain go\n * through lib/swap-router.ts (Synthra). Retained for a future Base deployment.\n *\n * Uniswap Trading API provider — swaps on Base via the hosted API.\n *\n * Uses the 3-step flow:\n * 1. POST /check_approval → check/submit token approval\n * 2. POST /quote → get optimal route + executable quote\n * 3. POST /swap → get transaction calldata to sign\n *\n * API key required — set via `sherwood config set --uniswap-api-key <key>`\n * or UNISWAP_API_KEY env var.\n *\n * Docs: https://docs.uniswap.org/api/trading-api\n * Key: https://developers.uniswap.org/\n */\n\nimport type { Address, Hex } from \"viem\";\nimport { isAddress, isHex, formatUnits } from \"viem\";\nimport type { SwapParams, SwapQuoteParams, TxResult, SwapQuote } from \"../types.js\";\nimport { getPublicClient, getAccount, writeContractWithRetry, sendTxWithRetry, waitForReceipt } from \"../lib/client.js\";\nimport { getChain } from \"../lib/network.js\";\nimport { getUniswapApiKey } from \"../lib/config.js\";\n\nconst API_BASE = \"https://trade-api.gateway.uniswap.org/v1\";\n\n// ── API Types ──\n\ninterface ApprovalResponse {\n approval: {\n to: Address;\n from: Address;\n data: Hex;\n value: string;\n chainId: number;\n } | null;\n}\n\n// CLASSIC route quote\ninterface ClassicQuote {\n routing: \"CLASSIC\" | \"WRAP\" | \"UNWRAP\";\n quote: {\n input: { token: string; amount: string };\n output: { token: string; amount: string };\n slippage: number;\n route: unknown[];\n gasFee: string;\n gasFeeUSD: string;\n gasUseEstimate: string;\n };\n permitData: Record<string, unknown> | null;\n}\n\n// UniswapX route quote (PRIORITY on Base)\ninterface UniswapXQuote {\n routing: \"DUTCH_V2\" | \"DUTCH_V3\" | \"PRIORITY\";\n quote: {\n orderInfo: {\n outputs: Array<{\n token: string;\n startAmount: string;\n endAmount: string;\n recipient: string;\n }>;\n input: { token: string; startAmount: string; endAmount: string };\n deadline: number;\n nonce: string;\n };\n encodedOrder: string;\n orderHash: string;\n };\n permitData: Record<string, unknown> | null;\n}\n\ntype QuoteResponse = ClassicQuote | UniswapXQuote;\n\ninterface SwapResponse {\n swap: {\n to: Address;\n from: Address;\n data: Hex;\n value: string;\n chainId: number;\n gasLimit?: string;\n };\n}\n\n// ── Helpers ──\n\nfunction getApiKey(): string {\n const key = getUniswapApiKey();\n if (!key) {\n throw new Error(\n \"Uniswap API key not configured. Run 'sherwood config set --uniswap-api-key <key>' \" +\n \"or set UNISWAP_API_KEY env var.\\n\" +\n \"Get your key at https://developers.uniswap.org/\",\n );\n }\n return key;\n}\n\nfunction apiHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": getApiKey(),\n \"x-universal-router-version\": \"2.0\",\n };\n}\n\nfunction isUniswapXRouting(routing: string): boolean {\n return routing === \"DUTCH_V2\" || routing === \"DUTCH_V3\" || routing === \"PRIORITY\";\n}\n\nfunction getOutputAmount(q: QuoteResponse): string {\n if (isUniswapXRouting(q.routing)) {\n const ux = q as UniswapXQuote;\n const firstOutput = ux.quote.orderInfo.outputs[0];\n if (!firstOutput) throw new Error(\"UniswapX quote has no outputs\");\n return firstOutput.startAmount; // best-case fill\n }\n return (q as ClassicQuote).quote.output.amount;\n}\n\nasync function fetchWithRetry(\n url: string,\n init: RequestInit,\n maxRetries = 3,\n): Promise<Response> {\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const response = await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(30_000),\n });\n if (response.status !== 429 && response.status < 500) return response;\n if (attempt === maxRetries) return response;\n\n const delay = Math.min(200 * Math.pow(2, attempt) + Math.random() * 100, 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n throw new Error(\"Unreachable\");\n}\n\n// ── Provider ──\n\nexport class UniswapProvider {\n /**\n * Get a quote from the Uniswap Trading API.\n * Returns the optimal route (CLASSIC, PRIORITY, or UniswapX).\n */\n async quote(params: SwapQuoteParams): Promise<SwapQuote> {\n const account = getAccount();\n const chainId = getChain().id;\n\n const body = {\n swapper: account.address,\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n tokenInChainId: String(chainId),\n tokenOutChainId: String(chainId),\n amount: params.amountIn.toString(),\n type: \"EXACT_INPUT\",\n slippageTolerance: 0.5,\n routingPreference: \"BEST_PRICE\",\n };\n\n const res = await fetchWithRetry(`${API_BASE}/quote`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const err = await res.text();\n throw new Error(`Uniswap quote failed (${res.status}): ${err}`);\n }\n\n const data = (await res.json()) as QuoteResponse;\n const amountOut = BigInt(getOutputAmount(data));\n\n return {\n amountOut,\n priceImpact: 0,\n route: `${data.routing}: ${params.tokenIn.slice(0, 8)}→${params.tokenOut.slice(0, 8)}`,\n };\n }\n\n /**\n * Get a full quote response (preserving the raw API response for swap execution).\n */\n async fullQuote(params: {\n tokenIn: Address;\n tokenOut: Address;\n amountIn: bigint;\n slippageTolerance?: number;\n }): Promise<{ quoteResponse: QuoteResponse; amountOut: bigint; routing: string }> {\n const account = getAccount();\n const chainId = getChain().id;\n\n const body = {\n swapper: account.address,\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n tokenInChainId: String(chainId),\n tokenOutChainId: String(chainId),\n amount: params.amountIn.toString(),\n type: \"EXACT_INPUT\",\n slippageTolerance: params.slippageTolerance ?? 0.5,\n routingPreference: \"BEST_PRICE\",\n };\n\n const res = await fetchWithRetry(`${API_BASE}/quote`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const err = await res.text();\n throw new Error(`Uniswap quote failed (${res.status}): ${err}`);\n }\n\n const quoteResponse = (await res.json()) as QuoteResponse;\n const amountOut = BigInt(getOutputAmount(quoteResponse));\n return { quoteResponse, amountOut, routing: quoteResponse.routing };\n }\n\n /**\n * Check and handle token approval for Uniswap.\n * Uses the Trading API's /check_approval endpoint.\n */\n async checkApproval(params: {\n token: Address;\n amount: bigint;\n }): Promise<void> {\n const account = getAccount();\n const chainId = getChain().id;\n const client = getPublicClient();\n\n const res = await fetchWithRetry(`${API_BASE}/check_approval`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify({\n walletAddress: account.address,\n token: params.token,\n amount: params.amount.toString(),\n chainId,\n }),\n });\n\n if (!res.ok) {\n const err = await res.text();\n throw new Error(`Approval check failed (${res.status}): ${err}`);\n }\n\n const data = (await res.json()) as ApprovalResponse;\n\n if (data.approval) {\n // API returns a ready-to-send transaction — use sendTxWithRetry for nonce safety\n const approvalHash = await sendTxWithRetry({\n to: data.approval.to,\n data: data.approval.data,\n value: BigInt(data.approval.value || \"0\"),\n account,\n chain: getChain(),\n });\n await waitForReceipt(approvalHash);\n }\n }\n\n /**\n * Execute a swap via the Uniswap Trading API.\n *\n * Full flow: check_approval → quote → swap → sign & broadcast.\n */\n async swap(params: SwapParams): Promise<TxResult> {\n const account = getAccount();\n const client = getPublicClient();\n\n // 1. Check approval (skip for native ETH)\n const ETH_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\n if (params.tokenIn !== ETH_ADDRESS) {\n await this.checkApproval({\n token: params.tokenIn,\n amount: params.amountIn,\n });\n }\n\n // 2. Get quote\n const { quoteResponse } = await this.fullQuote({\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n slippageTolerance: params.slippageTolerance ?? 0.5,\n });\n\n // 3. Prepare swap request — routing-aware permitData handling\n const quoteRaw = quoteResponse as unknown as Record<string, unknown>;\n const { permitData, ...cleanQuote } = quoteRaw;\n const swapRequest: Record<string, unknown> = { ...cleanQuote };\n\n // Sign permitData if present (required for both CLASSIC and UniswapX).\n // For CLASSIC routes using Permit2 (PermitSingle): include BOTH permitData + signature.\n // For UniswapX routes: include signature only (order-level signing, no permitData in body).\n if (permitData && typeof permitData === \"object\") {\n const typedData = permitData as {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n values: Record<string, unknown>;\n };\n const primaryType =\n Object.keys(typedData.types).find((k) => k !== \"EIP712Domain\") ?? \"PermitSingle\";\n const signature = await account.signTypedData({\n domain: typedData.domain as Record<string, unknown>,\n types: typedData.types as Record<string, Array<{ name: string; type: string }>>,\n primaryType,\n message: typedData.values,\n });\n swapRequest.signature = signature;\n // CLASSIC routes: /swap requires both permitData and signature\n // UniswapX routes: /swap requires signature only (order is in quote body)\n if (!isUniswapXRouting(quoteResponse.routing)) {\n swapRequest.permitData = permitData;\n }\n }\n\n // 4. Get swap transaction\n const swapRes = await fetchWithRetry(`${API_BASE}/swap`, {\n method: \"POST\",\n headers: apiHeaders(),\n body: JSON.stringify(swapRequest),\n });\n\n if (!swapRes.ok) {\n const err = await swapRes.text();\n throw new Error(`Uniswap swap failed (${swapRes.status}): ${err}`);\n }\n\n const swapData = (await swapRes.json()) as SwapResponse;\n\n // 5. Validate before broadcasting\n if (!swapData.swap?.data || swapData.swap.data === (\"\" as Hex) || swapData.swap.data === \"0x\") {\n throw new Error(\"Empty swap data — quote may have expired. Try again.\");\n }\n if (!isAddress(swapData.swap.to) || !isAddress(swapData.swap.from)) {\n throw new Error(\"Invalid address in swap response\");\n }\n\n // 6. Sign and broadcast with retry-aware sender\n // Apply a 1.5x buffer to the API's gasLimit: the Uniswap API under-estimates for WETH\n // and other non-USDC inputs where PermitSingle+transfer adds overhead.\n const gasLimit = swapData.swap.gasLimit\n ? (BigInt(swapData.swap.gasLimit) * 150n) / 100n\n : undefined;\n const hash = await sendTxWithRetry({\n to: swapData.swap.to,\n data: swapData.swap.data,\n value: BigInt(swapData.swap.value || \"0\"),\n gas: gasLimit,\n account,\n chain: getChain(),\n });\n\n const receipt = await waitForReceipt(hash);\n return {\n hash,\n success: receipt.status === \"success\",\n gasUsed: receipt.gasUsed,\n };\n }\n}\n","/**\n * Signal engine — aggregates on-chain, social, and fundamental data\n * into a composite buy/sell/hold recommendation.\n *\n * Sources:\n * On-chain: Nansen smart-money net flow (x402, ~$0.06)\n * Social: Venice inference with web search (X/Twitter sentiment)\n * Fundamental: Messari market data (x402, ~$0.20)\n *\n * No technical analysis — purely signal-driven.\n */\n\nimport type { Address } from \"viem\";\nimport { getResearchProvider } from \"../providers/research/index.js\";\nimport type { ResearchResult } from \"../providers/research/index.js\";\nimport { chatCompletion } from \"./venice.js\";\n\n// ── Types ──\n\nexport type SignalAction = \"buy\" | \"sell\" | \"hold\";\nexport type SignalSource = \"onchain\" | \"social\" | \"fundamental\";\n\nexport interface Signal {\n source: SignalSource;\n name: string;\n value: number; // -1.0 (bearish) to +1.0 (bullish)\n weight: number; // contribution to composite score\n raw: Record<string, unknown>;\n}\n\nexport interface SignalResult {\n action: SignalAction;\n confidence: number; // 0.0 to 1.0\n compositeScore: number; // -1.0 to +1.0\n signals: Signal[];\n costUsdc: string; // total x402 cost\n timestamp: number;\n}\n\nexport interface SignalConfig {\n buyThreshold: number; // composite score above this → buy (default 0.3)\n sellThreshold: number; // composite score below this → sell (default -0.2)\n}\n\nconst DEFAULT_CONFIG: SignalConfig = {\n buyThreshold: 0.3,\n sellThreshold: -0.2,\n};\n\n// ── Main Entry Point ──\n\n/**\n * Analyze a token using on-chain, social, and fundamental signals.\n * Runs all three data sources in parallel for speed.\n */\nexport async function analyzeToken(\n tokenAddress: Address,\n tokenSymbol: string,\n config?: Partial<SignalConfig>,\n): Promise<SignalResult> {\n const cfg = { ...DEFAULT_CONFIG, ...config };\n let totalCostUsdc = 0;\n\n // Run all three signals in parallel — each returns a Signal + cost\n const [onChain, social, fundamental] = await Promise.allSettled([\n getOnChainSignal(tokenSymbol),\n getSocialSignal(tokenAddress, tokenSymbol),\n getFundamentalSignal(tokenSymbol),\n ]);\n\n const signals: Signal[] = [];\n\n if (onChain.status === \"fulfilled\") {\n signals.push(onChain.value.signal);\n totalCostUsdc += onChain.value.costUsdc;\n }\n\n if (social.status === \"fulfilled\") {\n signals.push(social.value.signal);\n totalCostUsdc += social.value.costUsdc;\n }\n\n if (fundamental.status === \"fulfilled\") {\n signals.push(fundamental.value.signal);\n totalCostUsdc += fundamental.value.costUsdc;\n }\n\n // Compute composite score\n let weightedSum = 0;\n let totalWeight = 0;\n for (const s of signals) {\n weightedSum += s.value * s.weight;\n totalWeight += s.weight;\n }\n const compositeScore = totalWeight > 0 ? weightedSum / totalWeight : 0;\n\n // Confidence = average absolute signal strength\n const confidence =\n signals.length > 0\n ? signals.reduce((sum, s) => sum + Math.abs(s.value), 0) / signals.length\n : 0;\n\n // Decision\n let action: SignalAction = \"hold\";\n if (compositeScore >= cfg.buyThreshold && confidence >= 0.5) {\n action = \"buy\";\n } else if (compositeScore <= cfg.sellThreshold) {\n action = \"sell\";\n }\n\n return {\n action,\n confidence: Math.min(confidence, 1),\n compositeScore,\n signals,\n costUsdc: totalCostUsdc.toFixed(4),\n timestamp: Math.floor(Date.now() / 1000),\n };\n}\n\n// ── Individual Signal Sources ──\n\ninterface SignalWithCost {\n signal: Signal;\n costUsdc: number;\n}\n\n/**\n * On-chain signal: Nansen smart-money net flow.\n * Positive net flow (whales buying) → bullish.\n */\nasync function getOnChainSignal(tokenSymbol: string): Promise<SignalWithCost> {\n const nansen = getResearchProvider(\"nansen\");\n let result: ResearchResult;\n try {\n result = await nansen.query({ type: \"smart-money\", target: tokenSymbol });\n } catch {\n return {\n signal: {\n source: \"onchain\",\n name: \"smart_money_net_flow\",\n value: 0,\n weight: 0.40,\n raw: { error: \"nansen query failed\" },\n },\n costUsdc: 0,\n };\n }\n\n const data = result.data as Record<string, unknown>;\n\n // Extract net flow value — Nansen returns flow data in various formats\n const netFlow = extractNetFlow(data);\n // Normalize to -1..+1 range (clamp large values)\n const value = Math.max(-1, Math.min(1, netFlow));\n\n return {\n signal: {\n source: \"onchain\",\n name: \"smart_money_net_flow\",\n value,\n weight: 0.40,\n raw: data,\n },\n costUsdc: Number(result.costUsdc) || 0.06,\n };\n}\n\n/**\n * Social signal: Venice inference with web search for X/Twitter sentiment.\n */\nasync function getSocialSignal(\n tokenAddress: Address,\n tokenSymbol: string,\n): Promise<SignalWithCost> {\n try {\n const result = await chatCompletion({\n model: \"llama-3.3-70b\",\n messages: [\n {\n role: \"system\",\n content: `You are a crypto market sentiment analyst. Analyze current Twitter/X discourse about the given token. Return ONLY valid JSON with no markdown: {\"sentiment\": <number from -1.0 to 1.0>, \"reasoning\": \"<brief explanation>\", \"tweetCount\": <estimated tweets in last 24h>, \"keyTopics\": [\"topic1\", \"topic2\"]}. Positive sentiment means bullish discussion, influencer endorsements, positive news. Negative means FUD, rug pull warnings, community exodus. If you cannot find data, return {\"sentiment\": 0, \"reasoning\": \"insufficient data\", \"tweetCount\": 0, \"keyTopics\": []}.`,\n },\n {\n role: \"user\",\n content: `Analyze current X/Twitter sentiment for token ${tokenSymbol} (contract: ${tokenAddress} on Base chain). What is the social consensus in the last 24 hours?`,\n },\n ],\n temperature: 0.3,\n maxTokens: 500,\n enableWebSearch: true,\n });\n\n // Parse JSON from response\n const parsed = parseJsonResponse(result.content);\n const sentiment = typeof parsed.sentiment === \"number\"\n ? Math.max(-1, Math.min(1, parsed.sentiment))\n : 0;\n\n return {\n signal: {\n source: \"social\",\n name: \"x_sentiment\",\n value: sentiment,\n weight: 0.30,\n raw: parsed as Record<string, unknown>,\n },\n costUsdc: 0, // Venice inference is prepaid via sVVV, no per-call cost\n };\n } catch {\n return {\n signal: {\n source: \"social\",\n name: \"x_sentiment\",\n value: 0,\n weight: 0.30,\n raw: { error: \"venice inference failed\" },\n },\n costUsdc: 0,\n };\n }\n}\n\n/**\n * Fundamental signal: Messari market data — volume spike, market cap, ATH distance.\n */\nasync function getFundamentalSignal(\n tokenSymbol: string,\n): Promise<SignalWithCost> {\n const messari = getResearchProvider(\"messari\");\n let result: ResearchResult;\n try {\n result = await messari.query({ type: \"market\", target: tokenSymbol });\n } catch {\n return {\n signal: {\n source: \"fundamental\",\n name: \"market_fundamentals\",\n value: 0,\n weight: 0.30,\n raw: { error: \"messari query failed\" },\n },\n costUsdc: 0,\n };\n }\n\n const data = result.data as Record<string, unknown>;\n const value = scoreFundamentals(data);\n\n return {\n signal: {\n source: \"fundamental\",\n name: \"market_fundamentals\",\n value,\n weight: 0.30,\n raw: data,\n },\n costUsdc: Number(result.costUsdc) || 0.20,\n };\n}\n\n// ── Scoring Helpers ──\n\n/**\n * Extract net flow from Nansen smart-money response.\n * Normalizes to -1..+1 range.\n */\nfunction extractNetFlow(data: Record<string, unknown>): number {\n // Nansen returns various formats — try common paths\n const netFlow =\n (data.netFlow as number) ??\n (data.net_flow as number) ??\n ((data.inflow as number ?? 0) - (data.outflow as number ?? 0));\n\n if (typeof netFlow !== \"number\" || isNaN(netFlow)) return 0;\n\n // Normalize: scale by rough heuristic (> $1M net flow = strong signal)\n const normalized = netFlow / 1_000_000;\n return Math.max(-1, Math.min(1, normalized));\n}\n\n/**\n * Score fundamental data from Messari.\n *\n * Factors:\n * - Volume spike (24h vs 7d avg): > 3x = +0.5, > 2x = +0.25\n * - Market cap: < $10M with volume = +0.3 (high upside)\n * - ATH distance: > 80% down = +0.2 (recovery play), < 10% = -0.3 (possible top)\n */\nfunction scoreFundamentals(data: Record<string, unknown>): number {\n let score = 0;\n\n // Try to extract market data from nested Messari response\n const marketData = (data.marketData ?? data.market_data ?? data) as Record<string, unknown>;\n const athData = (data.allTimeHigh ?? data.ath ?? {}) as Record<string, unknown>;\n\n // Volume spike\n const vol24h = toNumber(marketData.volume_last_24_hours ?? marketData.volume24h);\n const vol7d = toNumber(marketData.volume_last_7_days ?? marketData.volume7d);\n if (vol24h > 0 && vol7d > 0) {\n const dailyAvg7d = vol7d / 7;\n const ratio = vol24h / dailyAvg7d;\n if (ratio > 3) score += 0.5;\n else if (ratio > 2) score += 0.25;\n else if (ratio < 0.5) score -= 0.25;\n }\n\n // Market cap\n const mcap = toNumber(marketData.current_marketcap_usd ?? marketData.marketCap);\n if (mcap > 0 && mcap < 10_000_000 && vol24h > 0) {\n score += 0.3; // small cap with volume = high upside potential\n } else if (mcap > 1_000_000_000) {\n score -= 0.15; // large cap = less upside for memecoins\n }\n\n // ATH distance\n const currentPrice = toNumber(marketData.price_usd ?? marketData.currentPrice);\n const athPrice = toNumber(athData.price ?? athData.athPrice);\n if (currentPrice > 0 && athPrice > 0) {\n const athDistance = ((athPrice - currentPrice) / athPrice) * 100;\n if (athDistance > 80) score += 0.2; // deep discount recovery play\n else if (athDistance < 10) score -= 0.3; // near ATH, potential top\n }\n\n return Math.max(-1, Math.min(1, score));\n}\n\nfunction toNumber(v: unknown): number {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\") return Number(v) || 0;\n return 0;\n}\n\n/**\n * Parse a JSON response from Venice, handling markdown fences and extra text.\n */\nfunction parseJsonResponse(content: string): Record<string, unknown> {\n // Strip markdown code fences if present\n let cleaned = content.trim();\n if (cleaned.startsWith(\"```\")) {\n cleaned = cleaned.replace(/^```(?:json)?\\n?/, \"\").replace(/\\n?```$/, \"\");\n }\n // Find the first { ... } block\n const start = cleaned.indexOf(\"{\");\n const end = cleaned.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n try {\n return JSON.parse(cleaned.slice(start, end + 1));\n } catch {\n // Fall through\n }\n }\n return { sentiment: 0, reasoning: \"failed to parse response\", raw: content };\n}\n","/**\n * Signal-based exit strategy for memecoin trades.\n *\n * Pure computation — no network calls. Evaluates a priority-ordered\n * set of exit conditions against the current position state.\n */\n\nimport type { SignalResult } from \"./signals.js\";\n\nexport interface ExitConfig {\n stopLossPct: number; // exit if PnL drops below this % (default 10)\n trailingStopPct: number; // exit if drawdown from high-water exceeds this % (0 = disabled)\n takeProfitPct: number; // exit if PnL reaches this % (0 = disabled, use signal exit)\n deadlineUnix: number; // force exit before this unix timestamp (0 = none)\n signalExitEnabled: boolean; // exit when signals flip bearish (default true)\n}\n\nexport type ExitReason =\n | \"stop_loss\"\n | \"trailing_stop\"\n | \"take_profit\"\n | \"deadline\"\n | \"signal_bearish\"\n | \"hold\";\n\nexport interface ExitCheck {\n shouldExit: boolean;\n reason: ExitReason;\n currentPnlPct: number;\n highWaterPnlPct: number;\n}\n\nexport const DEFAULT_EXIT_CONFIG: ExitConfig = {\n stopLossPct: 10,\n trailingStopPct: 0,\n takeProfitPct: 0,\n deadlineUnix: 0,\n signalExitEnabled: true,\n};\n\n/**\n * Check whether a position should be exited.\n *\n * Priority order (first match wins):\n * 1. Deadline passed\n * 2. Stop loss\n * 3. Trailing stop (drawdown from high-water mark)\n * 4. Take profit\n * 5. Signal-based (bearish signals with sufficient confidence)\n * 6. Hold\n */\nexport function checkExit(\n entryPrice: number,\n currentPrice: number,\n highWaterPrice: number,\n config: ExitConfig,\n signalResult?: SignalResult,\n): ExitCheck {\n if (entryPrice <= 0) {\n return { shouldExit: false, reason: \"hold\", currentPnlPct: 0, highWaterPnlPct: 0 };\n }\n\n const currentPnlPct = ((currentPrice - entryPrice) / entryPrice) * 100;\n const highWaterPnlPct = ((highWaterPrice - entryPrice) / entryPrice) * 100;\n\n // 1. Deadline\n if (config.deadlineUnix > 0 && Date.now() / 1000 > config.deadlineUnix) {\n return { shouldExit: true, reason: \"deadline\", currentPnlPct, highWaterPnlPct };\n }\n\n // 2. Stop loss\n if (currentPnlPct <= -config.stopLossPct) {\n return { shouldExit: true, reason: \"stop_loss\", currentPnlPct, highWaterPnlPct };\n }\n\n // 3. Trailing stop\n if (config.trailingStopPct > 0 && highWaterPrice > 0) {\n const drawdownPct = ((highWaterPrice - currentPrice) / highWaterPrice) * 100;\n if (drawdownPct >= config.trailingStopPct) {\n return { shouldExit: true, reason: \"trailing_stop\", currentPnlPct, highWaterPnlPct };\n }\n }\n\n // 4. Take profit\n if (config.takeProfitPct > 0 && currentPnlPct >= config.takeProfitPct) {\n return { shouldExit: true, reason: \"take_profit\", currentPnlPct, highWaterPnlPct };\n }\n\n // 5. Signal-based exit\n if (\n config.signalExitEnabled &&\n signalResult &&\n signalResult.action === \"sell\" &&\n signalResult.confidence > 0.4\n ) {\n return { shouldExit: true, reason: \"signal_bearish\", currentPnlPct, highWaterPnlPct };\n }\n\n // 6. Hold\n return { shouldExit: false, reason: \"hold\", currentPnlPct, highWaterPnlPct };\n}\n","/**\n * Position tracking for memecoin trades.\n *\n * Persists open and closed positions to ~/.sherwood/config.json.\n * Uses Uniswap QuoterV2 for current price lookups.\n */\n\nimport type { Address } from \"viem\";\nimport { formatUnits, parseUnits } from \"viem\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { getQuote } from \"./quote.js\";\nimport { TOKENS } from \"./addresses.js\";\nimport type { ExitConfig } from \"./exit-strategy.js\";\n\nexport interface Position {\n tokenAddress: Address;\n tokenSymbol: string;\n tokenDecimals: number;\n amountIn: string; // amount spent (human-readable, e.g. \"500\")\n amountOut: string; // tokens received (raw bigint as string)\n entryPrice: number; // input token per target token at entry\n highWaterPrice: number; // highest observed price since entry\n feeTier: number; // Uniswap fee tier used\n openedAt: number; // unix timestamp\n txHash: string; // buy tx hash\n exitConfig: ExitConfig; // per-position exit parameters\n inputTokenAddress?: Address; // token used to buy (default: USDC for backwards compat)\n inputTokenSymbol?: string; // symbol of input token (default: \"USDC\")\n inputTokenDecimals?: number; // decimals of input token (default: 6)\n}\n\nexport interface ClosedPosition extends Position {\n exitPrice: number;\n closedAt: number;\n exitTxHash: string;\n exitReason: string;\n pnlUsdc: number;\n pnlPct: number;\n}\n\n// ── Reads ──\n\nexport function getOpenPositions(): Position[] {\n const config = loadConfig();\n return (config.positions as Position[] | undefined) ?? [];\n}\n\nexport function getClosedPositions(): ClosedPosition[] {\n const config = loadConfig();\n return (config.closedPositions as ClosedPosition[] | undefined) ?? [];\n}\n\n// ── Writes ──\n\nexport function addPosition(pos: Position): void {\n const config = loadConfig();\n const positions = (config.positions as Position[] | undefined) ?? [];\n positions.push(pos);\n config.positions = positions;\n saveConfig(config);\n}\n\nexport function closePosition(\n tokenAddress: Address,\n exitData: {\n exitPrice: number;\n closedAt: number;\n exitTxHash: string;\n exitReason: string;\n pnlUsdc: number;\n pnlPct: number;\n },\n): void {\n const config = loadConfig();\n const positions = (config.positions as Position[] | undefined) ?? [];\n const idx = positions.findIndex(\n (p) => p.tokenAddress.toLowerCase() === tokenAddress.toLowerCase(),\n );\n if (idx === -1) {\n throw new Error(`No open position for ${tokenAddress}`);\n }\n\n const [pos] = positions.splice(idx, 1);\n const closed: ClosedPosition = { ...pos, ...exitData };\n\n const closedPositions = (config.closedPositions as ClosedPosition[] | undefined) ?? [];\n closedPositions.push(closed);\n\n config.positions = positions;\n config.closedPositions = closedPositions;\n saveConfig(config);\n}\n\nexport function updateHighWater(tokenAddress: Address, price: number): void {\n const config = loadConfig();\n const positions = (config.positions as Position[] | undefined) ?? [];\n const pos = positions.find(\n (p) => p.tokenAddress.toLowerCase() === tokenAddress.toLowerCase(),\n );\n if (pos && price > pos.highWaterPrice) {\n pos.highWaterPrice = price;\n config.positions = positions;\n saveConfig(config);\n }\n}\n\n// ── Price Lookup ──\n\n/**\n * Get the current USDC price of one token via Uniswap QuoterV2.\n * Quotes 1 full token unit against USDC.\n */\nexport async function getCurrentPrice(\n tokenAddress: Address,\n tokenDecimals: number,\n feeTier: number,\n): Promise<number> {\n const oneToken = parseUnits(\"1\", tokenDecimals);\n const usdc = TOKENS().USDC;\n\n const { amountOut } = await getQuote({\n tokenIn: tokenAddress,\n tokenOut: usdc,\n amountIn: oneToken,\n fee: feeTier,\n });\n\n // USDC has 6 decimals\n return Number(formatUnits(amountOut, 6));\n}\n"],"mappings":"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","names":["isAddress","parseUnits","formatUnits","ETH_ADDRESS","formatUnits","formatUnits","isAddress","client","parseUnits","formatUnits","writeContractWithRetry"]}
|
|
@@ -22,14 +22,14 @@ import {
|
|
|
22
22
|
removeDepositor,
|
|
23
23
|
setAgentFeeBps,
|
|
24
24
|
setVaultAddress
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-4BMAFJKO.js";
|
|
26
|
+
import "./chunk-5O3KO7ZI.js";
|
|
27
|
+
import "./chunk-ZTR2GPZO.js";
|
|
28
|
+
import "./chunk-I7TMY7AS.js";
|
|
29
|
+
import "./chunk-5BYJ3TGZ.js";
|
|
30
|
+
import "./chunk-ZW2VKCFZ.js";
|
|
31
31
|
import "./chunk-3TZIOAPH.js";
|
|
32
|
-
import "./chunk-
|
|
32
|
+
import "./chunk-XSP64L7L.js";
|
|
33
33
|
import "./chunk-VR4VHX4D.js";
|
|
34
34
|
export {
|
|
35
35
|
approveDepositor,
|
|
@@ -56,4 +56,4 @@ export {
|
|
|
56
56
|
setAgentFeeBps,
|
|
57
57
|
setVaultAddress
|
|
58
58
|
};
|
|
59
|
-
//# sourceMappingURL=vault-
|
|
59
|
+
//# sourceMappingURL=vault-GAIOZZPC.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getTextRecord
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-I7NXKJCG.js";
|
|
4
|
+
import "./chunk-I7TMY7AS.js";
|
|
5
5
|
import {
|
|
6
6
|
getAccount
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5BYJ3TGZ.js";
|
|
8
8
|
import {
|
|
9
9
|
getChainConfig
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZW2VKCFZ.js";
|
|
11
11
|
import {
|
|
12
12
|
cacheGroupId,
|
|
13
13
|
getCachedGroupId,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
requirePrivateKey,
|
|
17
17
|
saveConfig
|
|
18
18
|
} from "./chunk-3TZIOAPH.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-XSP64L7L.js";
|
|
20
20
|
|
|
21
21
|
// src/lib/xmtp.ts
|
|
22
22
|
import fs from "fs";
|
|
@@ -315,4 +315,4 @@ export {
|
|
|
315
315
|
sendReaction,
|
|
316
316
|
streamMessages
|
|
317
317
|
};
|
|
318
|
-
//# sourceMappingURL=xmtp-
|
|
318
|
+
//# sourceMappingURL=xmtp-A2KIQWGA.js.map
|