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.
Files changed (106) hide show
  1. package/.agents/skill/safehands/SKILL.md +169 -0
  2. package/LICENSE +21 -0
  3. package/README.md +382 -0
  4. package/contracts/RiskRegistry.json +149 -0
  5. package/contracts/RiskRegistry.sol +30 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +98 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/lib/constants.d.ts +173 -0
  11. package/dist/lib/constants.d.ts.map +1 -0
  12. package/dist/lib/constants.js +151 -0
  13. package/dist/lib/constants.js.map +1 -0
  14. package/dist/lib/dodoApi.d.ts +57 -0
  15. package/dist/lib/dodoApi.d.ts.map +1 -0
  16. package/dist/lib/dodoApi.js +123 -0
  17. package/dist/lib/dodoApi.js.map +1 -0
  18. package/dist/lib/pharosClient.d.ts +58 -0
  19. package/dist/lib/pharosClient.d.ts.map +1 -0
  20. package/dist/lib/pharosClient.js +51 -0
  21. package/dist/lib/pharosClient.js.map +1 -0
  22. package/dist/lib/riskEngine.d.ts +27 -0
  23. package/dist/lib/riskEngine.d.ts.map +1 -0
  24. package/dist/lib/riskEngine.js +284 -0
  25. package/dist/lib/riskEngine.js.map +1 -0
  26. package/dist/lib/testRpc.d.ts +2 -0
  27. package/dist/lib/testRpc.d.ts.map +1 -0
  28. package/dist/lib/testRpc.js +30 -0
  29. package/dist/lib/testRpc.js.map +1 -0
  30. package/dist/lib/testTools.d.ts +2 -0
  31. package/dist/lib/testTools.d.ts.map +1 -0
  32. package/dist/lib/testTools.js +263 -0
  33. package/dist/lib/testTools.js.map +1 -0
  34. package/dist/scripts/checkDeploy.d.ts +2 -0
  35. package/dist/scripts/checkDeploy.d.ts.map +1 -0
  36. package/dist/scripts/checkDeploy.js +25 -0
  37. package/dist/scripts/checkDeploy.js.map +1 -0
  38. package/dist/scripts/deployRegistry.d.ts +2 -0
  39. package/dist/scripts/deployRegistry.d.ts.map +1 -0
  40. package/dist/scripts/deployRegistry.js +101 -0
  41. package/dist/scripts/deployRegistry.js.map +1 -0
  42. package/dist/scripts/testRegistry.d.ts +2 -0
  43. package/dist/scripts/testRegistry.d.ts.map +1 -0
  44. package/dist/scripts/testRegistry.js +44 -0
  45. package/dist/scripts/testRegistry.js.map +1 -0
  46. package/dist/tools/approveToken.d.ts +60 -0
  47. package/dist/tools/approveToken.d.ts.map +1 -0
  48. package/dist/tools/approveToken.js +59 -0
  49. package/dist/tools/approveToken.js.map +1 -0
  50. package/dist/tools/assessRisk.d.ts +67 -0
  51. package/dist/tools/assessRisk.d.ts.map +1 -0
  52. package/dist/tools/assessRisk.js +71 -0
  53. package/dist/tools/assessRisk.js.map +1 -0
  54. package/dist/tools/checkAllowance.d.ts +37 -0
  55. package/dist/tools/checkAllowance.d.ts.map +1 -0
  56. package/dist/tools/checkAllowance.js +43 -0
  57. package/dist/tools/checkAllowance.js.map +1 -0
  58. package/dist/tools/estimateGas.d.ts +70 -0
  59. package/dist/tools/estimateGas.d.ts.map +1 -0
  60. package/dist/tools/estimateGas.js +129 -0
  61. package/dist/tools/estimateGas.js.map +1 -0
  62. package/dist/tools/executeSwap.d.ts +94 -0
  63. package/dist/tools/executeSwap.d.ts.map +1 -0
  64. package/dist/tools/executeSwap.js +107 -0
  65. package/dist/tools/executeSwap.js.map +1 -0
  66. package/dist/tools/getExecutionHistory.d.ts +52 -0
  67. package/dist/tools/getExecutionHistory.d.ts.map +1 -0
  68. package/dist/tools/getExecutionHistory.js +94 -0
  69. package/dist/tools/getExecutionHistory.js.map +1 -0
  70. package/dist/tools/getGasPrice.d.ts +26 -0
  71. package/dist/tools/getGasPrice.d.ts.map +1 -0
  72. package/dist/tools/getGasPrice.js +52 -0
  73. package/dist/tools/getGasPrice.js.map +1 -0
  74. package/dist/tools/getPoolInfo.d.ts +88 -0
  75. package/dist/tools/getPoolInfo.d.ts.map +1 -0
  76. package/dist/tools/getPoolInfo.js +99 -0
  77. package/dist/tools/getPoolInfo.js.map +1 -0
  78. package/dist/tools/getTokenPrice.d.ts +28 -0
  79. package/dist/tools/getTokenPrice.d.ts.map +1 -0
  80. package/dist/tools/getTokenPrice.js +79 -0
  81. package/dist/tools/getTokenPrice.js.map +1 -0
  82. package/dist/tools/getTransactionStatus.d.ts +58 -0
  83. package/dist/tools/getTransactionStatus.d.ts.map +1 -0
  84. package/dist/tools/getTransactionStatus.js +68 -0
  85. package/dist/tools/getTransactionStatus.js.map +1 -0
  86. package/dist/tools/getWalletBalance.d.ts +40 -0
  87. package/dist/tools/getWalletBalance.d.ts.map +1 -0
  88. package/dist/tools/getWalletBalance.js +71 -0
  89. package/dist/tools/getWalletBalance.js.map +1 -0
  90. package/dist/tools/publishRiskScore.d.ts +74 -0
  91. package/dist/tools/publishRiskScore.d.ts.map +1 -0
  92. package/dist/tools/publishRiskScore.js +70 -0
  93. package/dist/tools/publishRiskScore.js.map +1 -0
  94. package/dist/tools/queryRiskRegistry.d.ts +49 -0
  95. package/dist/tools/queryRiskRegistry.d.ts.map +1 -0
  96. package/dist/tools/queryRiskRegistry.js +61 -0
  97. package/dist/tools/queryRiskRegistry.js.map +1 -0
  98. package/dist/tools/sendPayment.d.ts +70 -0
  99. package/dist/tools/sendPayment.d.ts.map +1 -0
  100. package/dist/tools/sendPayment.js +68 -0
  101. package/dist/tools/sendPayment.js.map +1 -0
  102. package/dist/tools/simulateTransaction.d.ts +82 -0
  103. package/dist/tools/simulateTransaction.d.ts.map +1 -0
  104. package/dist/tools/simulateTransaction.js +89 -0
  105. package/dist/tools/simulateTransaction.js.map +1 -0
  106. package/package.json +61 -0
@@ -0,0 +1,70 @@
1
+ import { z } from "zod";
2
+ export declare const sendPaymentSchema: z.ZodObject<{
3
+ toAddress: z.ZodString;
4
+ amount: z.ZodString;
5
+ memo: z.ZodOptional<z.ZodString>;
6
+ walletAddress: z.ZodString;
7
+ privateKey: z.ZodString;
8
+ }, "strip", z.ZodTypeAny, {
9
+ amount: string;
10
+ privateKey: string;
11
+ toAddress: string;
12
+ walletAddress: string;
13
+ memo?: string | undefined;
14
+ }, {
15
+ amount: string;
16
+ privateKey: string;
17
+ toAddress: string;
18
+ walletAddress: string;
19
+ memo?: string | undefined;
20
+ }>;
21
+ export type SendPaymentInput = z.infer<typeof sendPaymentSchema>;
22
+ export declare const sendPaymentTool: {
23
+ name: string;
24
+ description: string;
25
+ inputSchema: z.ZodObject<{
26
+ toAddress: z.ZodString;
27
+ amount: z.ZodString;
28
+ memo: z.ZodOptional<z.ZodString>;
29
+ walletAddress: z.ZodString;
30
+ privateKey: z.ZodString;
31
+ }, "strip", z.ZodTypeAny, {
32
+ amount: string;
33
+ privateKey: string;
34
+ toAddress: string;
35
+ walletAddress: string;
36
+ memo?: string | undefined;
37
+ }, {
38
+ amount: string;
39
+ privateKey: string;
40
+ toAddress: string;
41
+ walletAddress: string;
42
+ memo?: string | undefined;
43
+ }>;
44
+ };
45
+ export declare function handleSendPayment(input: SendPaymentInput): Promise<{
46
+ success: boolean;
47
+ validation: {
48
+ addressValid: boolean;
49
+ balanceSufficient: boolean;
50
+ warnings: string[];
51
+ };
52
+ error: string;
53
+ txHash?: undefined;
54
+ explorerUrl?: undefined;
55
+ amountSent?: undefined;
56
+ gasUsed?: undefined;
57
+ } | {
58
+ success: boolean;
59
+ txHash: `0x${string}`;
60
+ explorerUrl: string;
61
+ amountSent: string;
62
+ gasUsed: string;
63
+ validation: {
64
+ addressValid: boolean;
65
+ balanceSufficient: boolean;
66
+ warnings: string[];
67
+ };
68
+ error?: undefined;
69
+ }>;
70
+ //# sourceMappingURL=sendPayment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendPayment.d.ts","sourceRoot":"","sources":["../../src/tools/sendPayment.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EAM5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;CAI3B,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;GAuD9D"}
@@ -0,0 +1,68 @@
1
+ // ─── Tool: send_payment ────────────────────────────────────────────────
2
+ import { z } from "zod";
3
+ import { publicClient, createPharosWalletClient, getExplorerUrl } from "../lib/pharosClient.js";
4
+ import { isAddress, parseEther, formatEther } from "viem";
5
+ import { MAX_BALANCE_USAGE_PCT } from "../lib/constants.js";
6
+ export const sendPaymentSchema = z.object({
7
+ toAddress: z.string(),
8
+ amount: z.string(),
9
+ memo: z.string().optional(),
10
+ walletAddress: z.string(),
11
+ privateKey: z.string(),
12
+ });
13
+ export const sendPaymentTool = {
14
+ name: "send_payment",
15
+ description: "Send native PHRS with pre-flight validation. Checks address validity, balance sufficiency, and warns on high exposure.",
16
+ inputSchema: sendPaymentSchema,
17
+ };
18
+ export async function handleSendPayment(input) {
19
+ const warnings = [];
20
+ const validation = { addressValid: false, balanceSufficient: false, warnings };
21
+ // Address validation
22
+ if (!isAddress(input.toAddress)) {
23
+ return { success: false, validation: { ...validation, addressValid: false }, error: "Invalid recipient address" };
24
+ }
25
+ validation.addressValid = true;
26
+ if (input.toAddress === "0x0000000000000000000000000000000000000000") {
27
+ return { success: false, validation, error: "Cannot send to zero address" };
28
+ }
29
+ if (input.toAddress.toLowerCase() === input.walletAddress.toLowerCase()) {
30
+ warnings.push("Sending to own address");
31
+ }
32
+ // Balance check
33
+ const amountWei = parseEther(input.amount);
34
+ const balance = await publicClient.getBalance({ address: input.walletAddress });
35
+ const gasEstimate = parseEther("0.01");
36
+ if (balance < amountWei + gasEstimate) {
37
+ return {
38
+ success: false,
39
+ validation: { ...validation, balanceSufficient: false, warnings: [...warnings, "Insufficient balance"] },
40
+ error: `Insufficient balance: have ${formatEther(balance)} PHRS, need ${input.amount} + gas`,
41
+ };
42
+ }
43
+ validation.balanceSufficient = true;
44
+ const usagePct = Number((amountWei * 100n) / balance);
45
+ if (usagePct > MAX_BALANCE_USAGE_PCT) {
46
+ warnings.push(`Using ${usagePct}% of wallet balance — high exposure`);
47
+ }
48
+ try {
49
+ const wallet = createPharosWalletClient(input.privateKey);
50
+ const txHash = await wallet.sendTransaction({
51
+ to: input.toAddress,
52
+ value: amountWei,
53
+ });
54
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
55
+ return {
56
+ success: receipt.status === "success",
57
+ txHash,
58
+ explorerUrl: getExplorerUrl(txHash),
59
+ amountSent: input.amount,
60
+ gasUsed: receipt.gasUsed.toString(),
61
+ validation,
62
+ };
63
+ }
64
+ catch (err) {
65
+ return { success: false, validation, error: `Payment failed: ${err.message}` };
66
+ }
67
+ }
68
+ //# sourceMappingURL=sendPayment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendPayment.js","sourceRoot":"","sources":["../../src/tools/sendPayment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+ export declare const simulateTransactionSchema: z.ZodObject<{
3
+ action: z.ZodEnum<["swap", "transfer"]>;
4
+ tokenIn: z.ZodOptional<z.ZodString>;
5
+ tokenOut: z.ZodOptional<z.ZodString>;
6
+ amount: z.ZodString;
7
+ toAddress: z.ZodOptional<z.ZodString>;
8
+ walletAddress: z.ZodString;
9
+ }, "strip", z.ZodTypeAny, {
10
+ amount: string;
11
+ action: "transfer" | "swap";
12
+ walletAddress: string;
13
+ tokenIn?: string | undefined;
14
+ tokenOut?: string | undefined;
15
+ toAddress?: string | undefined;
16
+ }, {
17
+ amount: string;
18
+ action: "transfer" | "swap";
19
+ walletAddress: string;
20
+ tokenIn?: string | undefined;
21
+ tokenOut?: string | undefined;
22
+ toAddress?: string | undefined;
23
+ }>;
24
+ export type SimulateTransactionInput = z.infer<typeof simulateTransactionSchema>;
25
+ export declare const simulateTransactionTool: {
26
+ name: string;
27
+ description: string;
28
+ inputSchema: z.ZodObject<{
29
+ action: z.ZodEnum<["swap", "transfer"]>;
30
+ tokenIn: z.ZodOptional<z.ZodString>;
31
+ tokenOut: z.ZodOptional<z.ZodString>;
32
+ amount: z.ZodString;
33
+ toAddress: z.ZodOptional<z.ZodString>;
34
+ walletAddress: z.ZodString;
35
+ }, "strip", z.ZodTypeAny, {
36
+ amount: string;
37
+ action: "transfer" | "swap";
38
+ walletAddress: string;
39
+ tokenIn?: string | undefined;
40
+ tokenOut?: string | undefined;
41
+ toAddress?: string | undefined;
42
+ }, {
43
+ amount: string;
44
+ action: "transfer" | "swap";
45
+ walletAddress: string;
46
+ tokenIn?: string | undefined;
47
+ tokenOut?: string | undefined;
48
+ toAddress?: string | undefined;
49
+ }>;
50
+ };
51
+ export declare function handleSimulateTransaction(input: SimulateTransactionInput): Promise<{
52
+ wouldSucceed: boolean;
53
+ gasEstimate: string;
54
+ revertReason: string;
55
+ balanceChanges: {
56
+ token: string;
57
+ delta: string;
58
+ }[];
59
+ warnings: string[];
60
+ expectedOutput?: undefined;
61
+ } | {
62
+ wouldSucceed: boolean;
63
+ expectedOutput: string;
64
+ gasEstimate: string;
65
+ revertReason: string;
66
+ balanceChanges: {
67
+ token: string;
68
+ delta: string;
69
+ }[];
70
+ warnings: string[];
71
+ } | {
72
+ wouldSucceed: boolean;
73
+ expectedOutput: string;
74
+ gasEstimate: string;
75
+ balanceChanges: {
76
+ token: string;
77
+ delta: string;
78
+ }[];
79
+ warnings: string[];
80
+ revertReason?: undefined;
81
+ }>;
82
+ //# sourceMappingURL=simulateTransaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulateTransaction.d.ts","sourceRoot":"","sources":["../../src/tools/simulateTransaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;EAOpC,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;;;;;eAExC,MAAM;eAAS,MAAM;;;;;;;;;;eAArB,MAAM;eAAS,MAAM;;;;;;;;eAArB,MAAM;eAAS,MAAM;;;;GA6E3D"}
@@ -0,0 +1,89 @@
1
+ // ─── Tool: simulate_transaction ────────────────────────────────────────
2
+ import { z } from "zod";
3
+ import { publicClient } from "../lib/pharosClient.js";
4
+ import { getDodoRoute } from "../lib/dodoApi.js";
5
+ import { parseEther, formatEther } from "viem";
6
+ export const simulateTransactionSchema = z.object({
7
+ action: z.enum(["swap", "transfer"]),
8
+ tokenIn: z.string().optional(),
9
+ tokenOut: z.string().optional(),
10
+ amount: z.string(),
11
+ toAddress: z.string().optional(),
12
+ walletAddress: z.string(),
13
+ });
14
+ export const simulateTransactionTool = {
15
+ name: "simulate_transaction",
16
+ description: "Dry run a swap or transfer via eth_call — no gas spent. Returns expected output, gas estimate, and revert reasons.",
17
+ inputSchema: simulateTransactionSchema,
18
+ };
19
+ export async function handleSimulateTransaction(input) {
20
+ const warnings = [];
21
+ const balanceChanges = [];
22
+ try {
23
+ if (input.action === "swap") {
24
+ if (!input.tokenIn || !input.tokenOut) {
25
+ return { wouldSucceed: false, gasEstimate: "0", revertReason: "tokenIn and tokenOut required for swap simulation", balanceChanges, warnings };
26
+ }
27
+ const quote = await getDodoRoute({
28
+ fromToken: input.tokenIn,
29
+ toToken: input.tokenOut,
30
+ amountHuman: input.amount,
31
+ walletAddress: input.walletAddress,
32
+ });
33
+ if (!quote.routeAvailable) {
34
+ return { wouldSucceed: false, gasEstimate: "0", revertReason: "No swap route available", balanceChanges, warnings };
35
+ }
36
+ // Simulate via eth_call
37
+ try {
38
+ await publicClient.call({
39
+ to: quote.to,
40
+ data: quote.calldata,
41
+ value: BigInt(quote.value),
42
+ account: input.walletAddress,
43
+ });
44
+ }
45
+ catch (err) {
46
+ const msg = err.message;
47
+ if (msg.includes("revert")) {
48
+ return { wouldSucceed: false, expectedOutput: quote.amountOut, gasEstimate: quote.gasLimit, revertReason: msg, balanceChanges, warnings };
49
+ }
50
+ warnings.push(`Simulation warning: ${msg}`);
51
+ }
52
+ balanceChanges.push({ token: input.tokenIn, delta: `-${input.amount}` });
53
+ balanceChanges.push({ token: input.tokenOut, delta: `+${quote.amountOut}` });
54
+ return { wouldSucceed: true, expectedOutput: quote.amountOut, gasEstimate: quote.gasLimit, balanceChanges, warnings };
55
+ }
56
+ // Transfer simulation
57
+ if (!input.toAddress) {
58
+ return { wouldSucceed: false, gasEstimate: "0", revertReason: "toAddress required for transfer simulation", balanceChanges, warnings };
59
+ }
60
+ const amountWei = parseEther(input.amount);
61
+ const balance = await publicClient.getBalance({ address: input.walletAddress });
62
+ if (balance < amountWei) {
63
+ return {
64
+ wouldSucceed: false,
65
+ gasEstimate: "21000",
66
+ revertReason: `Insufficient balance: have ${formatEther(balance)}, need ${input.amount}`,
67
+ balanceChanges,
68
+ warnings,
69
+ };
70
+ }
71
+ const gasEstimate = await publicClient.estimateGas({
72
+ to: input.toAddress,
73
+ value: amountWei,
74
+ account: input.walletAddress,
75
+ });
76
+ balanceChanges.push({ token: "PHRS", delta: `-${input.amount}` });
77
+ return {
78
+ wouldSucceed: true,
79
+ expectedOutput: input.amount,
80
+ gasEstimate: gasEstimate.toString(),
81
+ balanceChanges,
82
+ warnings,
83
+ };
84
+ }
85
+ catch (err) {
86
+ return { wouldSucceed: false, gasEstimate: "0", revertReason: err.message, balanceChanges, warnings };
87
+ }
88
+ }
89
+ //# sourceMappingURL=simulateTransaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulateTransaction.js","sourceRoot":"","sources":["../../src/tools/simulateTransaction.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "safehands-pharos",
3
+ "version": "1.0.0",
4
+ "description": "Risk-gating middleware for Pharos agents. Blocks dangerous swaps and transfers before they hit the chain.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": "./dist/index.js"
10
+ },
11
+ "bin": {
12
+ "safehands-pharos": "dist/index.js"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "contracts",
17
+ ".agents",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "start": "node dist/index.js",
24
+ "dev": "tsx src/index.ts",
25
+ "test:rpc": "tsx src/lib/testRpc.ts",
26
+ "test:all": "tsx src/lib/testTools.ts"
27
+ },
28
+ "keywords": [
29
+ "pharos",
30
+ "mcp",
31
+ "mcp-skill",
32
+ "defi",
33
+ "risk-engine",
34
+ "ai-agent",
35
+ "farodex",
36
+ "viem",
37
+ "atlantic-testnet",
38
+ "web3"
39
+ ],
40
+ "author": "SZtch",
41
+ "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/SZtch/safehands-pharos.git"
45
+ },
46
+ "homepage": "https://github.com/SZtch/safehands-pharos#readme",
47
+ "engines": {
48
+ "node": ">=18.0.0"
49
+ },
50
+ "dependencies": {
51
+ "@modelcontextprotocol/sdk": "^1.12.1",
52
+ "viem": "^2.31.3",
53
+ "zod": "^3.25.67"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^22.15.0",
57
+ "solc": "^0.8.28",
58
+ "tsx": "^4.20.3",
59
+ "typescript": "^5.8.3"
60
+ }
61
+ }