safehands-pharos 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skill/safehands/SKILL.md +169 -0
- package/LICENSE +21 -0
- package/README.md +382 -0
- package/contracts/RiskRegistry.json +149 -0
- package/contracts/RiskRegistry.sol +30 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +98 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/constants.d.ts +173 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +151 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/dodoApi.d.ts +57 -0
- package/dist/lib/dodoApi.d.ts.map +1 -0
- package/dist/lib/dodoApi.js +123 -0
- package/dist/lib/dodoApi.js.map +1 -0
- package/dist/lib/pharosClient.d.ts +58 -0
- package/dist/lib/pharosClient.d.ts.map +1 -0
- package/dist/lib/pharosClient.js +51 -0
- package/dist/lib/pharosClient.js.map +1 -0
- package/dist/lib/riskEngine.d.ts +27 -0
- package/dist/lib/riskEngine.d.ts.map +1 -0
- package/dist/lib/riskEngine.js +284 -0
- package/dist/lib/riskEngine.js.map +1 -0
- package/dist/lib/testRpc.d.ts +2 -0
- package/dist/lib/testRpc.d.ts.map +1 -0
- package/dist/lib/testRpc.js +30 -0
- package/dist/lib/testRpc.js.map +1 -0
- package/dist/lib/testTools.d.ts +2 -0
- package/dist/lib/testTools.d.ts.map +1 -0
- package/dist/lib/testTools.js +263 -0
- package/dist/lib/testTools.js.map +1 -0
- package/dist/scripts/checkDeploy.d.ts +2 -0
- package/dist/scripts/checkDeploy.d.ts.map +1 -0
- package/dist/scripts/checkDeploy.js +25 -0
- package/dist/scripts/checkDeploy.js.map +1 -0
- package/dist/scripts/deployRegistry.d.ts +2 -0
- package/dist/scripts/deployRegistry.d.ts.map +1 -0
- package/dist/scripts/deployRegistry.js +101 -0
- package/dist/scripts/deployRegistry.js.map +1 -0
- package/dist/scripts/testRegistry.d.ts +2 -0
- package/dist/scripts/testRegistry.d.ts.map +1 -0
- package/dist/scripts/testRegistry.js +44 -0
- package/dist/scripts/testRegistry.js.map +1 -0
- package/dist/tools/approveToken.d.ts +60 -0
- package/dist/tools/approveToken.d.ts.map +1 -0
- package/dist/tools/approveToken.js +59 -0
- package/dist/tools/approveToken.js.map +1 -0
- package/dist/tools/assessRisk.d.ts +67 -0
- package/dist/tools/assessRisk.d.ts.map +1 -0
- package/dist/tools/assessRisk.js +71 -0
- package/dist/tools/assessRisk.js.map +1 -0
- package/dist/tools/checkAllowance.d.ts +37 -0
- package/dist/tools/checkAllowance.d.ts.map +1 -0
- package/dist/tools/checkAllowance.js +43 -0
- package/dist/tools/checkAllowance.js.map +1 -0
- package/dist/tools/estimateGas.d.ts +70 -0
- package/dist/tools/estimateGas.d.ts.map +1 -0
- package/dist/tools/estimateGas.js +129 -0
- package/dist/tools/estimateGas.js.map +1 -0
- package/dist/tools/executeSwap.d.ts +94 -0
- package/dist/tools/executeSwap.d.ts.map +1 -0
- package/dist/tools/executeSwap.js +107 -0
- package/dist/tools/executeSwap.js.map +1 -0
- package/dist/tools/getExecutionHistory.d.ts +52 -0
- package/dist/tools/getExecutionHistory.d.ts.map +1 -0
- package/dist/tools/getExecutionHistory.js +94 -0
- package/dist/tools/getExecutionHistory.js.map +1 -0
- package/dist/tools/getGasPrice.d.ts +26 -0
- package/dist/tools/getGasPrice.d.ts.map +1 -0
- package/dist/tools/getGasPrice.js +52 -0
- package/dist/tools/getGasPrice.js.map +1 -0
- package/dist/tools/getPoolInfo.d.ts +88 -0
- package/dist/tools/getPoolInfo.d.ts.map +1 -0
- package/dist/tools/getPoolInfo.js +99 -0
- package/dist/tools/getPoolInfo.js.map +1 -0
- package/dist/tools/getTokenPrice.d.ts +28 -0
- package/dist/tools/getTokenPrice.d.ts.map +1 -0
- package/dist/tools/getTokenPrice.js +79 -0
- package/dist/tools/getTokenPrice.js.map +1 -0
- package/dist/tools/getTransactionStatus.d.ts +58 -0
- package/dist/tools/getTransactionStatus.d.ts.map +1 -0
- package/dist/tools/getTransactionStatus.js +68 -0
- package/dist/tools/getTransactionStatus.js.map +1 -0
- package/dist/tools/getWalletBalance.d.ts +40 -0
- package/dist/tools/getWalletBalance.d.ts.map +1 -0
- package/dist/tools/getWalletBalance.js +71 -0
- package/dist/tools/getWalletBalance.js.map +1 -0
- package/dist/tools/publishRiskScore.d.ts +74 -0
- package/dist/tools/publishRiskScore.d.ts.map +1 -0
- package/dist/tools/publishRiskScore.js +70 -0
- package/dist/tools/publishRiskScore.js.map +1 -0
- package/dist/tools/queryRiskRegistry.d.ts +49 -0
- package/dist/tools/queryRiskRegistry.d.ts.map +1 -0
- package/dist/tools/queryRiskRegistry.js +61 -0
- package/dist/tools/queryRiskRegistry.js.map +1 -0
- package/dist/tools/sendPayment.d.ts +70 -0
- package/dist/tools/sendPayment.d.ts.map +1 -0
- package/dist/tools/sendPayment.js +68 -0
- package/dist/tools/sendPayment.js.map +1 -0
- package/dist/tools/simulateTransaction.d.ts +82 -0
- package/dist/tools/simulateTransaction.d.ts.map +1 -0
- package/dist/tools/simulateTransaction.js +89 -0
- package/dist/tools/simulateTransaction.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// ─── Tool: execute_swap ────────────────────────────────────────────────
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { publicClient, createPharosWalletClient, getExplorerUrl } from "../lib/pharosClient.js";
|
|
4
|
+
import { getDodoRoute, isNativeToken, resolveTokenAddress, resolveTokenDecimals, toWei } from "../lib/dodoApi.js";
|
|
5
|
+
import { assessRisk } from "../lib/riskEngine.js";
|
|
6
|
+
import { DODO_APPROVE_ADDRESS, ERC20_ABI, RISK_BLOCK_THRESHOLD } from "../lib/constants.js";
|
|
7
|
+
export const executeSwapSchema = z.object({
|
|
8
|
+
tokenIn: z.string(),
|
|
9
|
+
tokenOut: z.string(),
|
|
10
|
+
amountIn: z.string(),
|
|
11
|
+
slippageTolerance: z.number().optional().default(3.225),
|
|
12
|
+
walletAddress: z.string(),
|
|
13
|
+
privateKey: z.string(),
|
|
14
|
+
bypassRiskCheck: z.boolean().optional().default(false),
|
|
15
|
+
});
|
|
16
|
+
export const executeSwapTool = {
|
|
17
|
+
name: "execute_swap",
|
|
18
|
+
description: "Swap tokens via FaroSwap with built-in risk gate. Runs risk assessment first, blocks if score > 80.",
|
|
19
|
+
inputSchema: executeSwapSchema,
|
|
20
|
+
};
|
|
21
|
+
export async function handleExecuteSwap(raw) {
|
|
22
|
+
const input = executeSwapSchema.parse(raw);
|
|
23
|
+
// 1. Risk assessment
|
|
24
|
+
let riskScore = 0;
|
|
25
|
+
let wasBlocked = false;
|
|
26
|
+
let blockReason;
|
|
27
|
+
if (!input.bypassRiskCheck) {
|
|
28
|
+
const risk = await assessRisk({
|
|
29
|
+
action: "swap",
|
|
30
|
+
tokenIn: input.tokenIn,
|
|
31
|
+
tokenOut: input.tokenOut,
|
|
32
|
+
amount: input.amountIn,
|
|
33
|
+
walletAddress: input.walletAddress,
|
|
34
|
+
});
|
|
35
|
+
riskScore = risk.riskScore;
|
|
36
|
+
if (riskScore > RISK_BLOCK_THRESHOLD) {
|
|
37
|
+
return {
|
|
38
|
+
success: false,
|
|
39
|
+
riskAssessment: { riskScore, wasBlocked: true, blockReason: risk.suggestion },
|
|
40
|
+
error: `Swap blocked — risk score ${riskScore}/100: ${risk.suggestion}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
// 2. Get DODO route
|
|
46
|
+
const quote = await getDodoRoute({
|
|
47
|
+
fromToken: input.tokenIn,
|
|
48
|
+
toToken: input.tokenOut,
|
|
49
|
+
amountHuman: input.amountIn,
|
|
50
|
+
walletAddress: input.walletAddress,
|
|
51
|
+
slippage: input.slippageTolerance,
|
|
52
|
+
});
|
|
53
|
+
if (!quote.routeAvailable) {
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
riskAssessment: { riskScore, wasBlocked: false },
|
|
57
|
+
error: "No swap route available — insufficient liquidity",
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const wallet = createPharosWalletClient(input.privateKey);
|
|
61
|
+
// 3. Approve if non-native token
|
|
62
|
+
if (!isNativeToken(input.tokenIn)) {
|
|
63
|
+
const tokenAddr = resolveTokenAddress(input.tokenIn);
|
|
64
|
+
const decimals = resolveTokenDecimals(input.tokenIn);
|
|
65
|
+
const amountWei = BigInt(toWei(input.amountIn, decimals));
|
|
66
|
+
const allowance = (await publicClient.readContract({
|
|
67
|
+
address: tokenAddr,
|
|
68
|
+
abi: ERC20_ABI,
|
|
69
|
+
functionName: "allowance",
|
|
70
|
+
args: [input.walletAddress, DODO_APPROVE_ADDRESS],
|
|
71
|
+
}));
|
|
72
|
+
if (allowance < amountWei) {
|
|
73
|
+
const approveHash = await wallet.writeContract({
|
|
74
|
+
address: tokenAddr,
|
|
75
|
+
abi: ERC20_ABI,
|
|
76
|
+
functionName: "approve",
|
|
77
|
+
args: [DODO_APPROVE_ADDRESS, amountWei * 2n],
|
|
78
|
+
});
|
|
79
|
+
await publicClient.waitForTransactionReceipt({ hash: approveHash });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// 4. Send swap tx
|
|
83
|
+
const txHash = await wallet.sendTransaction({
|
|
84
|
+
to: quote.to,
|
|
85
|
+
value: BigInt(quote.value),
|
|
86
|
+
data: quote.calldata,
|
|
87
|
+
gas: BigInt(quote.gasLimit),
|
|
88
|
+
});
|
|
89
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
90
|
+
return {
|
|
91
|
+
success: receipt.status === "success",
|
|
92
|
+
txHash,
|
|
93
|
+
explorerUrl: getExplorerUrl(txHash),
|
|
94
|
+
amountOut: quote.amountOut,
|
|
95
|
+
gasUsed: receipt.gasUsed.toString(),
|
|
96
|
+
riskAssessment: { riskScore, wasBlocked: false },
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
riskAssessment: { riskScore, wasBlocked: false },
|
|
103
|
+
error: `Swap failed: ${err.message}`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=executeSwap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeSwap.js","sourceRoot":"","sources":["../../src/tools/executeSwap.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE5F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACvD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CACvD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,qGAAqG;IAClH,WAAW,EAAE,iBAAiB;CAC/B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAqB;IAC3D,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3C,qBAAqB;IACrB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,WAA+B,CAAC;IAEpC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC;YAC5B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,QAAQ;YACtB,aAAa,EAAE,KAAK,CAAC,aAAa;SACnC,CAAC,CAAC;QACH,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAE3B,IAAI,SAAS,GAAG,oBAAoB,EAAE,CAAC;YACrC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,cAAc,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE;gBAC7E,KAAK,EAAE,6BAA6B,SAAS,SAAS,IAAI,CAAC,UAAU,EAAE;aACxE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,oBAAoB;QACpB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC;YAC/B,SAAS,EAAE,KAAK,CAAC,OAAO;YACxB,OAAO,EAAE,KAAK,CAAC,QAAQ;YACvB,WAAW,EAAE,KAAK,CAAC,QAAQ;YAC3B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,QAAQ,EAAE,KAAK,CAAC,iBAAiB;SAClC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,cAAc,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE;gBAChD,KAAK,EAAE,kDAAkD;aAC1D,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,UAA2B,CAAC,CAAC;QAE3E,iCAAiC;QACjC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;YAE1D,MAAM,SAAS,GAAG,CAAC,MAAM,YAAY,CAAC,YAAY,CAAC;gBACjD,OAAO,EAAE,SAAS;gBAClB,GAAG,EAAE,SAAS;gBACd,YAAY,EAAE,WAAW;gBACzB,IAAI,EAAE,CAAC,KAAK,CAAC,aAA8B,EAAE,oBAAoB,CAAC;aACnE,CAAC,CAAW,CAAC;YAEd,IAAI,SAAS,GAAG,SAAS,EAAE,CAAC;gBAC1B,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC;oBAC7C,OAAO,EAAE,SAAS;oBAClB,GAAG,EAAE,SAAS;oBACd,YAAY,EAAE,SAAS;oBACvB,IAAI,EAAE,CAAC,oBAAoB,EAAE,SAAS,GAAG,EAAE,CAAC;iBAC7C,CAAC,CAAC;gBACH,MAAM,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC;YAC1C,EAAE,EAAE,KAAK,CAAC,EAAmB;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAC1B,IAAI,EAAE,KAAK,CAAC,QAAyB;YACrC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC5B,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE/E,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS;YACrC,MAAM;YACN,WAAW,EAAE,cAAc,CAAC,MAAM,CAAC;YACnC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE;YACnC,cAAc,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE;SACjD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,cAAc,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE;YAChD,KAAK,EAAE,gBAAiB,GAAa,CAAC,OAAO,EAAE;SAChD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const getExecutionHistorySchema: z.ZodObject<{
|
|
3
|
+
walletAddress: z.ZodString;
|
|
4
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
5
|
+
filter: z.ZodDefault<z.ZodOptional<z.ZodEnum<["swap", "transfer", "all"]>>>;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
filter: "transfer" | "swap" | "all";
|
|
8
|
+
walletAddress: string;
|
|
9
|
+
limit: number;
|
|
10
|
+
}, {
|
|
11
|
+
walletAddress: string;
|
|
12
|
+
filter?: "transfer" | "swap" | "all" | undefined;
|
|
13
|
+
limit?: number | undefined;
|
|
14
|
+
}>;
|
|
15
|
+
export type GetExecutionHistoryInput = z.infer<typeof getExecutionHistorySchema>;
|
|
16
|
+
export declare const getExecutionHistoryTool: {
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
inputSchema: z.ZodObject<{
|
|
20
|
+
walletAddress: z.ZodString;
|
|
21
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
22
|
+
filter: z.ZodDefault<z.ZodOptional<z.ZodEnum<["swap", "transfer", "all"]>>>;
|
|
23
|
+
}, "strip", z.ZodTypeAny, {
|
|
24
|
+
filter: "transfer" | "swap" | "all";
|
|
25
|
+
walletAddress: string;
|
|
26
|
+
limit: number;
|
|
27
|
+
}, {
|
|
28
|
+
walletAddress: string;
|
|
29
|
+
filter?: "transfer" | "swap" | "all" | undefined;
|
|
30
|
+
limit?: number | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
33
|
+
export declare function handleGetExecutionHistory(input: GetExecutionHistoryInput): Promise<{
|
|
34
|
+
walletAddress: string;
|
|
35
|
+
totalFetched: number;
|
|
36
|
+
history: never[];
|
|
37
|
+
error: string;
|
|
38
|
+
} | {
|
|
39
|
+
walletAddress: string;
|
|
40
|
+
totalFetched: number;
|
|
41
|
+
history: {
|
|
42
|
+
txHash: string;
|
|
43
|
+
explorerUrl: string;
|
|
44
|
+
type: "swap" | "transfer" | "other";
|
|
45
|
+
timestamp: string;
|
|
46
|
+
status: "success" | "failed";
|
|
47
|
+
value: string;
|
|
48
|
+
details: string;
|
|
49
|
+
}[];
|
|
50
|
+
error?: undefined;
|
|
51
|
+
}>;
|
|
52
|
+
//# sourceMappingURL=getExecutionHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getExecutionHistory.d.ts","sourceRoot":"","sources":["../../src/tools/getExecutionHistory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;EAIpC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAEjF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;CAInC,CAAC;AAEF,wBAAsB,yBAAyB,CAAC,KAAK,EAAE,wBAAwB;;;;;;;;;gBAEnE,MAAM;qBACD,MAAM;cACb,MAAM,GAAG,UAAU,GAAG,OAAO;mBACxB,MAAM;gBACT,SAAS,GAAG,QAAQ;eACrB,MAAM;iBACJ,MAAM;;;GAiFlB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// ─── Tool: get_execution_history ───────────────────────────────────────
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { publicClient, getExplorerUrl } from "../lib/pharosClient.js";
|
|
4
|
+
import { DODO_ROUTE_PROXY_ADDRESS } from "../lib/constants.js";
|
|
5
|
+
import { formatEther } from "viem";
|
|
6
|
+
export const getExecutionHistorySchema = z.object({
|
|
7
|
+
walletAddress: z.string(),
|
|
8
|
+
limit: z.number().optional().default(20),
|
|
9
|
+
filter: z.enum(["swap", "transfer", "all"]).optional().default("all"),
|
|
10
|
+
});
|
|
11
|
+
export const getExecutionHistoryTool = {
|
|
12
|
+
name: "get_execution_history",
|
|
13
|
+
description: "Pull on-chain transaction history for a wallet on Pharos. Filters by swap, transfer, or all.",
|
|
14
|
+
inputSchema: getExecutionHistorySchema,
|
|
15
|
+
};
|
|
16
|
+
export async function handleGetExecutionHistory(input) {
|
|
17
|
+
const history = [];
|
|
18
|
+
try {
|
|
19
|
+
const blockNumber = await publicClient.getBlockNumber();
|
|
20
|
+
// Scan last ~500 blocks for transactions
|
|
21
|
+
const fromBlock = blockNumber > 500n ? blockNumber - 500n : 0n;
|
|
22
|
+
// Use eth_getLogs to find transactions involving the wallet
|
|
23
|
+
// For a more complete solution, we'd use an indexer. Here we check recent blocks.
|
|
24
|
+
const batchSize = 50;
|
|
25
|
+
let found = 0;
|
|
26
|
+
for (let b = blockNumber; b > fromBlock && found < input.limit; b -= 1n) {
|
|
27
|
+
try {
|
|
28
|
+
const block = await publicClient.getBlock({
|
|
29
|
+
blockNumber: b,
|
|
30
|
+
includeTransactions: true,
|
|
31
|
+
});
|
|
32
|
+
for (const tx of block.transactions) {
|
|
33
|
+
if (found >= input.limit)
|
|
34
|
+
break;
|
|
35
|
+
if (typeof tx === "string")
|
|
36
|
+
continue;
|
|
37
|
+
const isFrom = tx.from.toLowerCase() === input.walletAddress.toLowerCase();
|
|
38
|
+
const isTo = tx.to?.toLowerCase() === input.walletAddress.toLowerCase();
|
|
39
|
+
if (!isFrom && !isTo)
|
|
40
|
+
continue;
|
|
41
|
+
const isDodoSwap = tx.to?.toLowerCase() === DODO_ROUTE_PROXY_ADDRESS.toLowerCase();
|
|
42
|
+
const txType = isDodoSwap
|
|
43
|
+
? "swap"
|
|
44
|
+
: tx.value > 0n
|
|
45
|
+
? "transfer"
|
|
46
|
+
: "other";
|
|
47
|
+
if (input.filter !== "all" && txType !== input.filter)
|
|
48
|
+
continue;
|
|
49
|
+
// Get receipt for status
|
|
50
|
+
let status = "success";
|
|
51
|
+
try {
|
|
52
|
+
const receipt = await publicClient.getTransactionReceipt({ hash: tx.hash });
|
|
53
|
+
status = receipt.status === "success" ? "success" : "failed";
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// skip
|
|
57
|
+
}
|
|
58
|
+
history.push({
|
|
59
|
+
txHash: tx.hash,
|
|
60
|
+
explorerUrl: getExplorerUrl(tx.hash),
|
|
61
|
+
type: txType,
|
|
62
|
+
timestamp: new Date(Number(block.timestamp) * 1000).toISOString(),
|
|
63
|
+
status,
|
|
64
|
+
value: formatEther(tx.value),
|
|
65
|
+
details: isDodoSwap
|
|
66
|
+
? `Swap via FaroSwap (DODO)`
|
|
67
|
+
: isFrom
|
|
68
|
+
? `Sent ${formatEther(tx.value)} PHRS to ${tx.to}`
|
|
69
|
+
: `Received ${formatEther(tx.value)} PHRS from ${tx.from}`,
|
|
70
|
+
});
|
|
71
|
+
found++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// skip blocks that fail to load
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
return {
|
|
82
|
+
walletAddress: input.walletAddress,
|
|
83
|
+
totalFetched: 0,
|
|
84
|
+
history: [],
|
|
85
|
+
error: `Failed to fetch history: ${err.message}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
walletAddress: input.walletAddress,
|
|
90
|
+
totalFetched: history.length,
|
|
91
|
+
history,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=getExecutionHistory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getExecutionHistory.js","sourceRoot":"","sources":["../../src/tools/getExecutionHistory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const getGasPriceSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
3
|
+
export type GetGasPriceInput = z.input<typeof getGasPriceSchema>;
|
|
4
|
+
export declare const getGasPriceTool: {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
inputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
8
|
+
};
|
|
9
|
+
export declare function handleGetGasPrice(_raw: GetGasPriceInput): Promise<{
|
|
10
|
+
gasPriceGwei: string;
|
|
11
|
+
gasPriceWei: string;
|
|
12
|
+
trend: "low" | "high" | "normal";
|
|
13
|
+
recommendation: string;
|
|
14
|
+
estimates: {
|
|
15
|
+
nativeTransfer: {
|
|
16
|
+
gas: string;
|
|
17
|
+
costPHRS: string;
|
|
18
|
+
};
|
|
19
|
+
tokenSwap: {
|
|
20
|
+
gas: string;
|
|
21
|
+
costPHRS: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
timestamp: string;
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=getGasPrice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getGasPrice.d.ts","sourceRoot":"","sources":["../../src/tools/getGasPrice.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,iBAAiB,gDAAe,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,eAAO,MAAM,eAAe;;;;CAK3B,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB;;;;;;;;;;;;;;;;GAwC7D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// ─── Tool: get_gas_price ───────────────────────────────────────────────
|
|
2
|
+
// Fetches current gas price from Pharos RPC with trend analysis.
|
|
3
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { publicClient } from "../lib/pharosClient.js";
|
|
6
|
+
import { formatGwei } from "viem";
|
|
7
|
+
export const getGasPriceSchema = z.object({});
|
|
8
|
+
export const getGasPriceTool = {
|
|
9
|
+
name: "get_gas_price",
|
|
10
|
+
description: "Get the current gas price on Pharos Atlantic Testnet with trend classification (low/normal/high) and cost estimates.",
|
|
11
|
+
inputSchema: getGasPriceSchema,
|
|
12
|
+
};
|
|
13
|
+
export async function handleGetGasPrice(_raw) {
|
|
14
|
+
const gasPrice = await publicClient.getGasPrice();
|
|
15
|
+
const gasPriceGwei = parseFloat(formatGwei(gasPrice));
|
|
16
|
+
// Classify trend based on Pharos testnet typical gas ranges
|
|
17
|
+
let trend;
|
|
18
|
+
let recommendation;
|
|
19
|
+
if (gasPriceGwei <= 5) {
|
|
20
|
+
trend = "low";
|
|
21
|
+
recommendation = "Gas is cheap. Good time to execute transactions.";
|
|
22
|
+
}
|
|
23
|
+
else if (gasPriceGwei <= 50) {
|
|
24
|
+
trend = "normal";
|
|
25
|
+
recommendation = "Gas is at normal levels. Proceed with standard transactions.";
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
trend = "high";
|
|
29
|
+
recommendation = "Gas is elevated. Consider waiting or reducing transaction complexity.";
|
|
30
|
+
}
|
|
31
|
+
// Estimate costs for common operations
|
|
32
|
+
const transferCostWei = gasPrice * 21000n;
|
|
33
|
+
const swapCostWei = gasPrice * 250000n; // typical swap gas
|
|
34
|
+
return {
|
|
35
|
+
gasPriceGwei: gasPriceGwei.toFixed(4),
|
|
36
|
+
gasPriceWei: gasPrice.toString(),
|
|
37
|
+
trend,
|
|
38
|
+
recommendation,
|
|
39
|
+
estimates: {
|
|
40
|
+
nativeTransfer: {
|
|
41
|
+
gas: "21,000",
|
|
42
|
+
costPHRS: (Number(transferCostWei) / 1e18).toFixed(8),
|
|
43
|
+
},
|
|
44
|
+
tokenSwap: {
|
|
45
|
+
gas: "~250,000",
|
|
46
|
+
costPHRS: (Number(swapCostWei) / 1e18).toFixed(8),
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=getGasPrice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getGasPrice.js","sourceRoot":"","sources":["../../src/tools/getGasPrice.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,iEAAiE;AACjE,2EAA2E;AAE3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAElC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAI9C,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,sHAAsH;IACxH,WAAW,EAAE,iBAAiB;CAC/B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAsB;IAC5D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,CAAC;IAClD,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEtD,4DAA4D;IAC5D,IAAI,KAAgC,CAAC;IACrC,IAAI,cAAsB,CAAC;IAE3B,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,KAAK,GAAG,KAAK,CAAC;QACd,cAAc,GAAG,kDAAkD,CAAC;IACtE,CAAC;SAAM,IAAI,YAAY,IAAI,EAAE,EAAE,CAAC;QAC9B,KAAK,GAAG,QAAQ,CAAC;QACjB,cAAc,GAAG,8DAA8D,CAAC;IAClF,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,MAAM,CAAC;QACf,cAAc,GAAG,uEAAuE,CAAC;IAC3F,CAAC;IAED,uCAAuC;IACvC,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC1C,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,mBAAmB;IAE3D,OAAO;QACL,YAAY,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,WAAW,EAAE,QAAQ,CAAC,QAAQ,EAAE;QAChC,KAAK;QACL,cAAc;QACd,SAAS,EAAE;YACT,cAAc,EAAE;gBACd,GAAG,EAAE,QAAQ;gBACb,QAAQ,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;aACtD;YACD,SAAS,EAAE;gBACT,GAAG,EAAE,UAAU;gBACf,QAAQ,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;aAClD;SACF;QACD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const getPoolInfoSchema: z.ZodObject<{
|
|
3
|
+
tokenA: z.ZodEnum<["PHRS", "USDC", "USDT"]>;
|
|
4
|
+
tokenB: z.ZodEnum<["PHRS", "USDC", "USDT"]>;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
tokenA: "PHRS" | "USDT" | "USDC";
|
|
7
|
+
tokenB: "PHRS" | "USDT" | "USDC";
|
|
8
|
+
}, {
|
|
9
|
+
tokenA: "PHRS" | "USDT" | "USDC";
|
|
10
|
+
tokenB: "PHRS" | "USDT" | "USDC";
|
|
11
|
+
}>;
|
|
12
|
+
export type GetPoolInfoInput = z.input<typeof getPoolInfoSchema>;
|
|
13
|
+
export declare const getPoolInfoTool: {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
inputSchema: z.ZodObject<{
|
|
17
|
+
tokenA: z.ZodEnum<["PHRS", "USDC", "USDT"]>;
|
|
18
|
+
tokenB: z.ZodEnum<["PHRS", "USDC", "USDT"]>;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
tokenA: "PHRS" | "USDT" | "USDC";
|
|
21
|
+
tokenB: "PHRS" | "USDT" | "USDC";
|
|
22
|
+
}, {
|
|
23
|
+
tokenA: "PHRS" | "USDT" | "USDC";
|
|
24
|
+
tokenB: "PHRS" | "USDT" | "USDC";
|
|
25
|
+
}>;
|
|
26
|
+
};
|
|
27
|
+
export declare function handleGetPoolInfo(raw: GetPoolInfoInput): Promise<{
|
|
28
|
+
pair: string;
|
|
29
|
+
error: string;
|
|
30
|
+
available?: undefined;
|
|
31
|
+
message?: undefined;
|
|
32
|
+
timestamp?: undefined;
|
|
33
|
+
priceRatio?: undefined;
|
|
34
|
+
priceImpact?: undefined;
|
|
35
|
+
pricePerFromToken?: undefined;
|
|
36
|
+
pricePerToToken?: undefined;
|
|
37
|
+
fee?: undefined;
|
|
38
|
+
liquidity?: undefined;
|
|
39
|
+
source?: undefined;
|
|
40
|
+
chainId?: undefined;
|
|
41
|
+
} | {
|
|
42
|
+
pair: string;
|
|
43
|
+
available: boolean;
|
|
44
|
+
message: string;
|
|
45
|
+
timestamp: string;
|
|
46
|
+
error?: undefined;
|
|
47
|
+
priceRatio?: undefined;
|
|
48
|
+
priceImpact?: undefined;
|
|
49
|
+
pricePerFromToken?: undefined;
|
|
50
|
+
pricePerToToken?: undefined;
|
|
51
|
+
fee?: undefined;
|
|
52
|
+
liquidity?: undefined;
|
|
53
|
+
source?: undefined;
|
|
54
|
+
chainId?: undefined;
|
|
55
|
+
} | {
|
|
56
|
+
pair: string;
|
|
57
|
+
available: boolean;
|
|
58
|
+
priceRatio: string;
|
|
59
|
+
priceImpact: string;
|
|
60
|
+
pricePerFromToken: string;
|
|
61
|
+
pricePerToToken: string;
|
|
62
|
+
fee: string;
|
|
63
|
+
liquidity: string | {
|
|
64
|
+
baseLiquidity: string;
|
|
65
|
+
quoteLiquidity: string;
|
|
66
|
+
poolType: string;
|
|
67
|
+
};
|
|
68
|
+
source: string;
|
|
69
|
+
chainId: number;
|
|
70
|
+
timestamp: string;
|
|
71
|
+
error?: undefined;
|
|
72
|
+
message?: undefined;
|
|
73
|
+
} | {
|
|
74
|
+
pair: string;
|
|
75
|
+
available: boolean;
|
|
76
|
+
error: string;
|
|
77
|
+
timestamp: string;
|
|
78
|
+
message?: undefined;
|
|
79
|
+
priceRatio?: undefined;
|
|
80
|
+
priceImpact?: undefined;
|
|
81
|
+
pricePerFromToken?: undefined;
|
|
82
|
+
pricePerToToken?: undefined;
|
|
83
|
+
fee?: undefined;
|
|
84
|
+
liquidity?: undefined;
|
|
85
|
+
source?: undefined;
|
|
86
|
+
chainId?: undefined;
|
|
87
|
+
}>;
|
|
88
|
+
//# sourceMappingURL=getPoolInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getPoolInfo.d.ts","sourceRoot":"","sources":["../../src/tools/getPoolInfo.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,iBAAiB;;;;;;;;;EAG5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;CAK3B,CAAC;AAiBF,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAyDrB,MAAM;wBAAkB,MAAM;kBAAY,MAAM;;;;;;;;;;;;;;;;;;;;;GA6CvF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// ─── Tool: get_pool_info ───────────────────────────────────────────────
|
|
2
|
+
// Fetches DODO liquidity pool data for a token pair on Pharos.
|
|
3
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { resolveTokenAddress } from "../lib/dodoApi.js";
|
|
6
|
+
import { DODO_API_BASE, DODO_API_KEY, CHAIN_ID } from "../lib/constants.js";
|
|
7
|
+
export const getPoolInfoSchema = z.object({
|
|
8
|
+
tokenA: z.enum(["PHRS", "USDC", "USDT"]).describe("First token in the pair"),
|
|
9
|
+
tokenB: z.enum(["PHRS", "USDC", "USDT"]).describe("Second token in the pair"),
|
|
10
|
+
});
|
|
11
|
+
export const getPoolInfoTool = {
|
|
12
|
+
name: "get_pool_info",
|
|
13
|
+
description: "Fetch DODO liquidity pool info for a token pair on Pharos. Returns liquidity, volume, fees, and price ratio.",
|
|
14
|
+
inputSchema: getPoolInfoSchema,
|
|
15
|
+
};
|
|
16
|
+
export async function handleGetPoolInfo(raw) {
|
|
17
|
+
const input = getPoolInfoSchema.parse(raw);
|
|
18
|
+
if (input.tokenA === input.tokenB) {
|
|
19
|
+
return {
|
|
20
|
+
pair: `${input.tokenA}/${input.tokenB}`,
|
|
21
|
+
error: "Cannot query pool for identical tokens",
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const addrA = resolveTokenAddress(input.tokenA);
|
|
25
|
+
const addrB = resolveTokenAddress(input.tokenB);
|
|
26
|
+
// Try DODO pair list endpoint
|
|
27
|
+
const pairUrl = `${DODO_API_BASE}/route-service/v2/widget/getdodoroute` +
|
|
28
|
+
`?chainId=${CHAIN_ID}` +
|
|
29
|
+
`&fromTokenAddress=${addrA}` +
|
|
30
|
+
`&toTokenAddress=${addrB}` +
|
|
31
|
+
`&fromAmount=1000000000000000000` + // 1 token in wei (18 decimals)
|
|
32
|
+
`&userAddr=0x0000000000000000000000000000000000000001` +
|
|
33
|
+
`&slippage=3` +
|
|
34
|
+
`&source=dodoV2AndMixWasm` +
|
|
35
|
+
`&estimateGas=true` +
|
|
36
|
+
`&apikey=${DODO_API_KEY}`;
|
|
37
|
+
try {
|
|
38
|
+
const routeResponse = await fetch(pairUrl);
|
|
39
|
+
const routeJson = (await routeResponse.json());
|
|
40
|
+
if (!routeJson.data || routeJson.status !== 200) {
|
|
41
|
+
return {
|
|
42
|
+
pair: `${input.tokenA}/${input.tokenB}`,
|
|
43
|
+
available: false,
|
|
44
|
+
message: "No active DODO liquidity pool found for this pair on Pharos",
|
|
45
|
+
timestamp: new Date().toISOString(),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const d = routeJson.data;
|
|
49
|
+
const resAmount = parseFloat(String(d.resAmount || "0"));
|
|
50
|
+
const priceImpact = parseFloat(String(d.priceImpact || "0"));
|
|
51
|
+
const fee = parseFloat(String(d.baseFeeAmount || "0"));
|
|
52
|
+
const pricePerFrom = parseFloat(String(d.resPricePerFromToken || "0"));
|
|
53
|
+
const pricePerTo = parseFloat(String(d.resPricePerToToken || "0"));
|
|
54
|
+
// Also try the pools endpoint for liquidity data
|
|
55
|
+
let liquidityInfo = null;
|
|
56
|
+
try {
|
|
57
|
+
const poolsUrl = `${DODO_API_BASE}/dodo-pair/list` +
|
|
58
|
+
`?chainId=${CHAIN_ID}` +
|
|
59
|
+
`&baseToken=${addrA}` +
|
|
60
|
+
`"eToken=${addrB}` +
|
|
61
|
+
`&apikey=${DODO_API_KEY}`;
|
|
62
|
+
const poolsResp = await fetch(poolsUrl);
|
|
63
|
+
const poolsJson = (await poolsResp.json());
|
|
64
|
+
if (poolsJson.data?.list && poolsJson.data.list.length > 0) {
|
|
65
|
+
const pool = poolsJson.data.list[0];
|
|
66
|
+
liquidityInfo = {
|
|
67
|
+
baseLiquidity: pool.baseLiquidity || "unknown",
|
|
68
|
+
quoteLiquidity: pool.quoteLiquidity || "unknown",
|
|
69
|
+
poolType: pool.type || "unknown",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Pool list endpoint may not be available — non-critical
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
pair: `${input.tokenA}/${input.tokenB}`,
|
|
78
|
+
available: true,
|
|
79
|
+
priceRatio: resAmount > 0 ? `1 ${input.tokenA} = ${resAmount} ${input.tokenB}` : "unavailable",
|
|
80
|
+
priceImpact: `${priceImpact.toFixed(4)}%`,
|
|
81
|
+
pricePerFromToken: pricePerFrom > 0 ? pricePerFrom.toFixed(6) : "unavailable",
|
|
82
|
+
pricePerToToken: pricePerTo > 0 ? pricePerTo.toFixed(6) : "unavailable",
|
|
83
|
+
fee: fee > 0 ? fee.toString() : "included in quote",
|
|
84
|
+
liquidity: liquidityInfo || "Query via route API (pool list unavailable)",
|
|
85
|
+
source: "DODO Aggregation API",
|
|
86
|
+
chainId: CHAIN_ID,
|
|
87
|
+
timestamp: new Date().toISOString(),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
return {
|
|
92
|
+
pair: `${input.tokenA}/${input.tokenB}`,
|
|
93
|
+
available: false,
|
|
94
|
+
error: `Failed to fetch pool info: ${err.message}`,
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=getPoolInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getPoolInfo.js","sourceRoot":"","sources":["../../src/tools/getPoolInfo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const getTokenPriceSchema: z.ZodObject<{
|
|
3
|
+
token: z.ZodEnum<["PHRS", "USDC", "USDT"]>;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
token: "PHRS" | "USDT" | "USDC";
|
|
6
|
+
}, {
|
|
7
|
+
token: "PHRS" | "USDT" | "USDC";
|
|
8
|
+
}>;
|
|
9
|
+
export type GetTokenPriceInput = z.input<typeof getTokenPriceSchema>;
|
|
10
|
+
export declare const getTokenPriceTool: {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
inputSchema: z.ZodObject<{
|
|
14
|
+
token: z.ZodEnum<["PHRS", "USDC", "USDT"]>;
|
|
15
|
+
}, "strip", z.ZodTypeAny, {
|
|
16
|
+
token: "PHRS" | "USDT" | "USDC";
|
|
17
|
+
}, {
|
|
18
|
+
token: "PHRS" | "USDT" | "USDC";
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
export declare function handleGetTokenPrice(raw: GetTokenPriceInput): Promise<{
|
|
22
|
+
token: string;
|
|
23
|
+
priceUsd: string;
|
|
24
|
+
priceInPHRS: string;
|
|
25
|
+
source: string;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
}>;
|
|
28
|
+
//# sourceMappingURL=getTokenPrice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTokenPrice.d.ts","sourceRoot":"","sources":["../../src/tools/getTokenPrice.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,mBAAmB;;;;;;EAE9B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAErE,eAAO,MAAM,iBAAiB;;;;;;;;;;CAK7B,CAAC;AAKF,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,kBAAkB;;;;;;GAuEhE"}
|