@tamago-labs/wayfind-mcp 0.1.0 → 0.2.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/index.js CHANGED
@@ -39,9 +39,70 @@ var GetWalletAddressTool = {
39
39
  }
40
40
  };
41
41
 
42
+ // src/mcp/wayfind/get_tokens_tool.ts
43
+ var import_zod = require("zod");
44
+ var WayfindGetTokensTool = {
45
+ name: "wayfind_get_tokens",
46
+ description: "List all tokenized stocks with prices and market data",
47
+ schema: {
48
+ chain: import_zod.z.string().optional().describe("Filter by blockchain (e.g., 'solana', 'ethereum')")
49
+ },
50
+ handler: async (agent, input) => {
51
+ return agent.wayfindFetch("/tokens", input?.chain ? { chain: input.chain } : void 0);
52
+ }
53
+ };
54
+
55
+ // src/mcp/wayfind/get_tokenized_stocks_tool.ts
56
+ var import_zod2 = require("zod");
57
+ var WayfindGetTokenizedStocksTool = {
58
+ name: "wayfind_get_tokenized_stocks",
59
+ description: "Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)",
60
+ schema: {
61
+ ticker: import_zod2.z.string().describe("Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')")
62
+ },
63
+ handler: async (agent, input) => {
64
+ return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);
65
+ }
66
+ };
67
+
68
+ // src/mcp/wayfind/get_risk_profile_tool.ts
69
+ var WayfindGetRiskProfileTool = {
70
+ name: "wayfind_get_risk_profile",
71
+ description: "Get the user's portfolio risk profile including overall score, label, and answers",
72
+ schema: {},
73
+ handler: async (agent, _input) => {
74
+ return agent.wayfindFetch("/risk-profile");
75
+ }
76
+ };
77
+
78
+ // src/mcp/wayfind/get_market_overview_tool.ts
79
+ var WayfindGetMarketOverviewTool = {
80
+ name: "wayfind_get_market_overview",
81
+ description: "Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens",
82
+ schema: {},
83
+ handler: async (agent, _input) => {
84
+ return agent.wayfindFetch("/market-overview");
85
+ }
86
+ };
87
+
88
+ // src/mcp/wayfind/get_pre_ipo_tool.ts
89
+ var WayfindGetPreIpoTool = {
90
+ name: "wayfind_get_pre_ipo",
91
+ description: "List pre-IPO markets with mark prices and valuations",
92
+ schema: {},
93
+ handler: async (agent, _input) => {
94
+ return agent.wayfindFetch("/pre-ipo");
95
+ }
96
+ };
97
+
42
98
  // src/mcp/index.ts
43
- var SolanaMcpTools = {
44
- GetWalletAddressTool
99
+ var McpTools = {
100
+ SolanaGetWalletAddress: GetWalletAddressTool,
101
+ WayfindGetTokens: WayfindGetTokensTool,
102
+ WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,
103
+ WayfindGetRiskProfile: WayfindGetRiskProfileTool,
104
+ WayfindGetMarketOverview: WayfindGetMarketOverviewTool,
105
+ WayfindGetPreIpo: WayfindGetPreIpoTool
45
106
  };
46
107
 
47
108
  // src/agent/index.ts
@@ -55,20 +116,33 @@ function validateEnvironment() {
55
116
  throw new Error("Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)");
56
117
  }
57
118
  const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
58
- return { privateKey, rpcUrl };
119
+ const wayfindApiKey = process.env.WAYFIND_API_KEY || "e1ee8520-305a-49b5-a2de-3e1a7e6078c0";
120
+ const wayfindApiUrl = process.env.WAYFIND_API_URL || "https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws";
121
+ return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };
59
122
  }
60
123
 
61
124
  // src/agent/index.ts
62
125
  var Agent = class _Agent {
63
- constructor(walletAddress) {
126
+ constructor(walletAddress, config) {
64
127
  this.walletAddress = walletAddress;
128
+ this.config = config;
65
129
  }
66
130
  static async create() {
67
131
  const config = validateEnvironment();
68
132
  const decoded = import_bs58.default.decode(config.privateKey);
69
133
  const seed = decoded.slice(0, 32);
70
134
  const signer = await (0, import_kit.createKeyPairSignerFromPrivateKeyBytes)(seed, false);
71
- return new _Agent(signer.address);
135
+ return new _Agent(signer.address, config);
136
+ }
137
+ async wayfindFetch(path, params) {
138
+ const url = new URL(`${this.config.wayfindApiUrl}${path}`);
139
+ if (params) {
140
+ for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
141
+ }
142
+ const res = await fetch(url.toString(), {
143
+ headers: { "x-api-key": this.config.wayfindApiKey }
144
+ });
145
+ return res.json();
72
146
  }
73
147
  };
74
148
 
@@ -78,7 +152,7 @@ function createMcpServer(agent) {
78
152
  name: "wayfind-solana-mcp",
79
153
  version: "0.1.0"
80
154
  });
81
- for (const [_key, tool] of Object.entries(SolanaMcpTools)) {
155
+ for (const [_key, tool] of Object.entries(McpTools)) {
82
156
  server.tool(tool.name, tool.description, tool.schema, async (params) => {
83
157
  try {
84
158
  const result = await tool.handler(agent, params);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { SolanaMcpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(SolanaMcpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\n\nexport const SolanaMcpTools: Record<string, McpTool> = {\n GetWalletAddressTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n\n private constructor(walletAddress: string) {\n this.walletAddress = walletAddress;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address);\n }\n}\n","export interface SolanaConfig {\n privateKey: string;\n rpcUrl: string;\n}\n\nexport function validateEnvironment(): SolanaConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n return { privateKey, rpcUrl };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,iBAA0B;AAC1B,mBAAqC;;;ACC9B,IAAM,uBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,SAAS,OAAO,OAAc,WAAgC;AAC5D,WAAO;AAAA,MACL,eAAe,MAAM;AAAA,IACvB;AAAA,EACF;AACF;;;ACVO,IAAM,iBAA0C;AAAA,EACrD;AACF;;;ACLA,iBAAuD;AACvD,kBAAiB;;;ACIV,SAAS,sBAAoC;AAClD,QAAM,aAAa,QAAQ,IAAI;AAC/B,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,mFAAmF;AAAA,EACrG;AACA,QAAM,SAAS,QAAQ,IAAI,kBAAkB;AAC7C,SAAO,EAAE,YAAY,OAAO;AAC9B;;;ADRO,IAAM,QAAN,MAAM,OAAM;AAAA,EAGT,YAAY,eAAuB;AACzC,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,aAAa,SAAyB;AACpC,UAAM,SAAS,oBAAoB;AACnC,UAAM,UAAU,YAAAA,QAAK,OAAO,OAAO,UAAU;AAC7C,UAAM,OAAO,QAAQ,MAAM,GAAG,EAAE;AAChC,UAAM,SAAS,UAAM,mDAAuC,MAAM,KAAK;AACvE,WAAO,IAAI,OAAM,OAAO,OAAO;AAAA,EACjC;AACF;;;AHXA,SAAS,gBAAgB,OAAc;AACrC,QAAM,SAAS,IAAI,qBAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAED,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,WAAO,KAAK,KAAK,MAAM,KAAK,aAAa,KAAK,QAAQ,OAAO,WAA8B;AACzF,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,QAAQ,OAAO,MAAM;AAC/C,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,QAC5E;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB,CAAC;AAAA,QACrG;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,OAAO;AACpB,QAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAM,SAAS,gBAAgB,KAAK;AACpC,QAAM,YAAY,IAAI,kCAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK;","names":["bs58"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/wayfind/get_tokens_tool.ts","../src/mcp/wayfind/get_tokenized_stocks_tool.ts","../src/mcp/wayfind/get_risk_profile_tool.ts","../src/mcp/wayfind/get_market_overview_tool.ts","../src/mcp/wayfind/get_pre_ipo_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { McpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(McpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokensTool: McpTool = {\n name: \"wayfind_get_tokens\",\n description: \"List all tokenized stocks with prices and market data\",\n schema: {\n chain: z.string().optional().describe(\"Filter by blockchain (e.g., 'solana', 'ethereum')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(\"/tokens\", input?.chain ? { chain: input.chain } : undefined);\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokenizedStocksTool: McpTool = {\n name: \"wayfind_get_tokenized_stocks\",\n description: \"Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)\",\n schema: {\n ticker: z.string().describe(\"Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetRiskProfileTool: McpTool = {\n name: \"wayfind_get_risk_profile\",\n description: \"Get the user's portfolio risk profile including overall score, label, and answers\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/risk-profile\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetMarketOverviewTool: McpTool = {\n name: \"wayfind_get_market_overview\",\n description: \"Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/market-overview\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetPreIpoTool: McpTool = {\n name: \"wayfind_get_pre_ipo\",\n description: \"List pre-IPO markets with mark prices and valuations\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/pre-ipo\");\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\nimport { WayfindGetTokensTool } from \"./wayfind/get_tokens_tool\";\nimport { WayfindGetTokenizedStocksTool } from \"./wayfind/get_tokenized_stocks_tool\";\nimport { WayfindGetRiskProfileTool } from \"./wayfind/get_risk_profile_tool\";\nimport { WayfindGetMarketOverviewTool } from \"./wayfind/get_market_overview_tool\";\nimport { WayfindGetPreIpoTool } from \"./wayfind/get_pre_ipo_tool\";\n\nexport const McpTools: Record<string, McpTool> = {\n SolanaGetWalletAddress: GetWalletAddressTool,\n WayfindGetTokens: WayfindGetTokensTool,\n WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,\n WayfindGetRiskProfile: WayfindGetRiskProfileTool,\n WayfindGetMarketOverview: WayfindGetMarketOverviewTool,\n WayfindGetPreIpo: WayfindGetPreIpoTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment, type AppConfig } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n private config: AppConfig;\n\n private constructor(walletAddress: string, config: AppConfig) {\n this.walletAddress = walletAddress;\n this.config = config;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address, config);\n }\n\n async wayfindFetch(path: string, params?: Record<string, string>) {\n const url = new URL(`${this.config.wayfindApiUrl}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n const res = await fetch(url.toString(), {\n headers: { \"x-api-key\": this.config.wayfindApiKey },\n });\n return res.json();\n }\n}\n","export interface AppConfig {\n privateKey: string;\n rpcUrl: string;\n wayfindApiKey: string;\n wayfindApiUrl: string;\n}\n\nexport function validateEnvironment(): AppConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n const wayfindApiKey = process.env.WAYFIND_API_KEY || \"e1ee8520-305a-49b5-a2de-3e1a7e6078c0\";\n const wayfindApiUrl = process.env.WAYFIND_API_URL || \"https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws\";\n return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };\n}\n"],"mappings":"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","names":["import_zod","bs58"]}
package/dist/index.mjs CHANGED
@@ -16,9 +16,70 @@ var GetWalletAddressTool = {
16
16
  }
17
17
  };
18
18
 
19
+ // src/mcp/wayfind/get_tokens_tool.ts
20
+ import { z } from "zod";
21
+ var WayfindGetTokensTool = {
22
+ name: "wayfind_get_tokens",
23
+ description: "List all tokenized stocks with prices and market data",
24
+ schema: {
25
+ chain: z.string().optional().describe("Filter by blockchain (e.g., 'solana', 'ethereum')")
26
+ },
27
+ handler: async (agent, input) => {
28
+ return agent.wayfindFetch("/tokens", input?.chain ? { chain: input.chain } : void 0);
29
+ }
30
+ };
31
+
32
+ // src/mcp/wayfind/get_tokenized_stocks_tool.ts
33
+ import { z as z2 } from "zod";
34
+ var WayfindGetTokenizedStocksTool = {
35
+ name: "wayfind_get_tokenized_stocks",
36
+ description: "Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)",
37
+ schema: {
38
+ ticker: z2.string().describe("Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')")
39
+ },
40
+ handler: async (agent, input) => {
41
+ return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);
42
+ }
43
+ };
44
+
45
+ // src/mcp/wayfind/get_risk_profile_tool.ts
46
+ var WayfindGetRiskProfileTool = {
47
+ name: "wayfind_get_risk_profile",
48
+ description: "Get the user's portfolio risk profile including overall score, label, and answers",
49
+ schema: {},
50
+ handler: async (agent, _input) => {
51
+ return agent.wayfindFetch("/risk-profile");
52
+ }
53
+ };
54
+
55
+ // src/mcp/wayfind/get_market_overview_tool.ts
56
+ var WayfindGetMarketOverviewTool = {
57
+ name: "wayfind_get_market_overview",
58
+ description: "Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens",
59
+ schema: {},
60
+ handler: async (agent, _input) => {
61
+ return agent.wayfindFetch("/market-overview");
62
+ }
63
+ };
64
+
65
+ // src/mcp/wayfind/get_pre_ipo_tool.ts
66
+ var WayfindGetPreIpoTool = {
67
+ name: "wayfind_get_pre_ipo",
68
+ description: "List pre-IPO markets with mark prices and valuations",
69
+ schema: {},
70
+ handler: async (agent, _input) => {
71
+ return agent.wayfindFetch("/pre-ipo");
72
+ }
73
+ };
74
+
19
75
  // src/mcp/index.ts
20
- var SolanaMcpTools = {
21
- GetWalletAddressTool
76
+ var McpTools = {
77
+ SolanaGetWalletAddress: GetWalletAddressTool,
78
+ WayfindGetTokens: WayfindGetTokensTool,
79
+ WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,
80
+ WayfindGetRiskProfile: WayfindGetRiskProfileTool,
81
+ WayfindGetMarketOverview: WayfindGetMarketOverviewTool,
82
+ WayfindGetPreIpo: WayfindGetPreIpoTool
22
83
  };
23
84
 
24
85
  // src/agent/index.ts
@@ -32,20 +93,33 @@ function validateEnvironment() {
32
93
  throw new Error("Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)");
33
94
  }
34
95
  const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
35
- return { privateKey, rpcUrl };
96
+ const wayfindApiKey = process.env.WAYFIND_API_KEY || "e1ee8520-305a-49b5-a2de-3e1a7e6078c0";
97
+ const wayfindApiUrl = process.env.WAYFIND_API_URL || "https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws";
98
+ return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };
36
99
  }
37
100
 
38
101
  // src/agent/index.ts
39
102
  var Agent = class _Agent {
40
- constructor(walletAddress) {
103
+ constructor(walletAddress, config) {
41
104
  this.walletAddress = walletAddress;
105
+ this.config = config;
42
106
  }
43
107
  static async create() {
44
108
  const config = validateEnvironment();
45
109
  const decoded = bs58.decode(config.privateKey);
46
110
  const seed = decoded.slice(0, 32);
47
111
  const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);
48
- return new _Agent(signer.address);
112
+ return new _Agent(signer.address, config);
113
+ }
114
+ async wayfindFetch(path, params) {
115
+ const url = new URL(`${this.config.wayfindApiUrl}${path}`);
116
+ if (params) {
117
+ for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
118
+ }
119
+ const res = await fetch(url.toString(), {
120
+ headers: { "x-api-key": this.config.wayfindApiKey }
121
+ });
122
+ return res.json();
49
123
  }
50
124
  };
51
125
 
@@ -55,7 +129,7 @@ function createMcpServer(agent) {
55
129
  name: "wayfind-solana-mcp",
56
130
  version: "0.1.0"
57
131
  });
58
- for (const [_key, tool] of Object.entries(SolanaMcpTools)) {
132
+ for (const [_key, tool] of Object.entries(McpTools)) {
59
133
  server.tool(tool.name, tool.description, tool.schema, async (params) => {
60
134
  try {
61
135
  const result = await tool.handler(agent, params);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { SolanaMcpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(SolanaMcpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\n\nexport const SolanaMcpTools: Record<string, McpTool> = {\n GetWalletAddressTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n\n private constructor(walletAddress: string) {\n this.walletAddress = walletAddress;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address);\n }\n}\n","export interface SolanaConfig {\n privateKey: string;\n rpcUrl: string;\n}\n\nexport function validateEnvironment(): SolanaConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n return { privateKey, rpcUrl };\n}\n"],"mappings":";;;AAEA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;;;ACC9B,IAAM,uBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,SAAS,OAAO,OAAc,WAAgC;AAC5D,WAAO;AAAA,MACL,eAAe,MAAM;AAAA,IACvB;AAAA,EACF;AACF;;;ACVO,IAAM,iBAA0C;AAAA,EACrD;AACF;;;ACLA,SAAS,8CAA8C;AACvD,OAAO,UAAU;;;ACIV,SAAS,sBAAoC;AAClD,QAAM,aAAa,QAAQ,IAAI;AAC/B,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,mFAAmF;AAAA,EACrG;AACA,QAAM,SAAS,QAAQ,IAAI,kBAAkB;AAC7C,SAAO,EAAE,YAAY,OAAO;AAC9B;;;ADRO,IAAM,QAAN,MAAM,OAAM;AAAA,EAGT,YAAY,eAAuB;AACzC,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,aAAa,SAAyB;AACpC,UAAM,SAAS,oBAAoB;AACnC,UAAM,UAAU,KAAK,OAAO,OAAO,UAAU;AAC7C,UAAM,OAAO,QAAQ,MAAM,GAAG,EAAE;AAChC,UAAM,SAAS,MAAM,uCAAuC,MAAM,KAAK;AACvE,WAAO,IAAI,OAAM,OAAO,OAAO;AAAA,EACjC;AACF;;;AHXA,SAAS,gBAAgB,OAAc;AACrC,QAAM,SAAS,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAED,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,WAAO,KAAK,KAAK,MAAM,KAAK,aAAa,KAAK,QAAQ,OAAO,WAA8B;AACzF,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,QAAQ,OAAO,MAAM;AAC/C,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,QAC5E;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB,CAAC;AAAA,QACrG;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,OAAO;AACpB,QAAM,QAAQ,MAAM,MAAM,OAAO;AACjC,QAAM,SAAS,gBAAgB,KAAK;AACpC,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/mcp/solana/get_wallet_address_tool.ts","../src/mcp/wayfind/get_tokens_tool.ts","../src/mcp/wayfind/get_tokenized_stocks_tool.ts","../src/mcp/wayfind/get_risk_profile_tool.ts","../src/mcp/wayfind/get_market_overview_tool.ts","../src/mcp/wayfind/get_pre_ipo_tool.ts","../src/mcp/index.ts","../src/agent/index.ts","../src/config.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { McpTools } from \"./mcp\";\nimport { Agent } from \"./agent\";\n\nfunction createMcpServer(agent: Agent) {\n const server = new McpServer({\n name: \"wayfind-solana-mcp\",\n version: \"0.1.0\",\n });\n\n for (const [_key, tool] of Object.entries(McpTools)) {\n server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n try {\n const result = await tool.handler(agent, params);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: error instanceof Error ? error.message : \"Unknown error\" }],\n };\n }\n });\n }\n\n return server;\n}\n\nasync function main() {\n const agent = await Agent.create();\n const server = createMcpServer(agent);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain();\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const GetWalletAddressTool: McpTool = {\n name: \"solana_get_wallet_address\",\n description: \"Get the Solana wallet address derived from the configured private key\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return {\n walletAddress: agent.walletAddress,\n };\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokensTool: McpTool = {\n name: \"wayfind_get_tokens\",\n description: \"List all tokenized stocks with prices and market data\",\n schema: {\n chain: z.string().optional().describe(\"Filter by blockchain (e.g., 'solana', 'ethereum')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(\"/tokens\", input?.chain ? { chain: input.chain } : undefined);\n },\n};\n","import { z } from \"zod\";\nimport { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetTokenizedStocksTool: McpTool = {\n name: \"wayfind_get_tokenized_stocks\",\n description: \"Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)\",\n schema: {\n ticker: z.string().describe(\"Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')\"),\n },\n handler: async (agent: Agent, input: Record<string, any>) => {\n return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetRiskProfileTool: McpTool = {\n name: \"wayfind_get_risk_profile\",\n description: \"Get the user's portfolio risk profile including overall score, label, and answers\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/risk-profile\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetMarketOverviewTool: McpTool = {\n name: \"wayfind_get_market_overview\",\n description: \"Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/market-overview\");\n },\n};\n","import { Agent } from \"../../agent\";\nimport type { McpTool } from \"../../types\";\n\nexport const WayfindGetPreIpoTool: McpTool = {\n name: \"wayfind_get_pre_ipo\",\n description: \"List pre-IPO markets with mark prices and valuations\",\n schema: {},\n handler: async (agent: Agent, _input: Record<string, any>) => {\n return agent.wayfindFetch(\"/pre-ipo\");\n },\n};\n","import type { McpTool } from \"../types\";\nimport { GetWalletAddressTool } from \"./solana/get_wallet_address_tool\";\nimport { WayfindGetTokensTool } from \"./wayfind/get_tokens_tool\";\nimport { WayfindGetTokenizedStocksTool } from \"./wayfind/get_tokenized_stocks_tool\";\nimport { WayfindGetRiskProfileTool } from \"./wayfind/get_risk_profile_tool\";\nimport { WayfindGetMarketOverviewTool } from \"./wayfind/get_market_overview_tool\";\nimport { WayfindGetPreIpoTool } from \"./wayfind/get_pre_ipo_tool\";\n\nexport const McpTools: Record<string, McpTool> = {\n SolanaGetWalletAddress: GetWalletAddressTool,\n WayfindGetTokens: WayfindGetTokensTool,\n WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,\n WayfindGetRiskProfile: WayfindGetRiskProfileTool,\n WayfindGetMarketOverview: WayfindGetMarketOverviewTool,\n WayfindGetPreIpo: WayfindGetPreIpoTool,\n};\n","import { createKeyPairSignerFromPrivateKeyBytes } from \"@solana/kit\";\nimport bs58 from \"bs58\";\nimport { validateEnvironment, type AppConfig } from \"../config\";\n\nexport class Agent {\n public walletAddress: string;\n private config: AppConfig;\n\n private constructor(walletAddress: string, config: AppConfig) {\n this.walletAddress = walletAddress;\n this.config = config;\n }\n\n static async create(): Promise<Agent> {\n const config = validateEnvironment();\n const decoded = bs58.decode(config.privateKey);\n const seed = decoded.slice(0, 32);\n const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);\n return new Agent(signer.address, config);\n }\n\n async wayfindFetch(path: string, params?: Record<string, string>) {\n const url = new URL(`${this.config.wayfindApiUrl}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n const res = await fetch(url.toString(), {\n headers: { \"x-api-key\": this.config.wayfindApiKey },\n });\n return res.json();\n }\n}\n","export interface AppConfig {\n privateKey: string;\n rpcUrl: string;\n wayfindApiKey: string;\n wayfindApiUrl: string;\n}\n\nexport function validateEnvironment(): AppConfig {\n const privateKey = process.env.SOLANA_PRIVATE_KEY;\n if (!privateKey) {\n throw new Error(\"Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)\");\n }\n const rpcUrl = process.env.SOLANA_RPC_URL || \"https://api.mainnet-beta.solana.com\";\n const wayfindApiKey = process.env.WAYFIND_API_KEY || \"e1ee8520-305a-49b5-a2de-3e1a7e6078c0\";\n const wayfindApiUrl = process.env.WAYFIND_API_URL || \"https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws\";\n return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };\n}\n"],"mappings":"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","names":["z"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamago-labs/wayfind-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -1,12 +1,14 @@
1
1
  import { createKeyPairSignerFromPrivateKeyBytes } from "@solana/kit";
2
2
  import bs58 from "bs58";
3
- import { validateEnvironment } from "../config";
3
+ import { validateEnvironment, type AppConfig } from "../config";
4
4
 
5
5
  export class Agent {
6
6
  public walletAddress: string;
7
+ private config: AppConfig;
7
8
 
8
- private constructor(walletAddress: string) {
9
+ private constructor(walletAddress: string, config: AppConfig) {
9
10
  this.walletAddress = walletAddress;
11
+ this.config = config;
10
12
  }
11
13
 
12
14
  static async create(): Promise<Agent> {
@@ -14,6 +16,17 @@ export class Agent {
14
16
  const decoded = bs58.decode(config.privateKey);
15
17
  const seed = decoded.slice(0, 32);
16
18
  const signer = await createKeyPairSignerFromPrivateKeyBytes(seed, false);
17
- return new Agent(signer.address);
19
+ return new Agent(signer.address, config);
20
+ }
21
+
22
+ async wayfindFetch(path: string, params?: Record<string, string>) {
23
+ const url = new URL(`${this.config.wayfindApiUrl}${path}`);
24
+ if (params) {
25
+ for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
26
+ }
27
+ const res = await fetch(url.toString(), {
28
+ headers: { "x-api-key": this.config.wayfindApiKey },
29
+ });
30
+ return res.json();
18
31
  }
19
32
  }
package/src/config.ts CHANGED
@@ -1,13 +1,17 @@
1
- export interface SolanaConfig {
1
+ export interface AppConfig {
2
2
  privateKey: string;
3
3
  rpcUrl: string;
4
+ wayfindApiKey: string;
5
+ wayfindApiUrl: string;
4
6
  }
5
7
 
6
- export function validateEnvironment(): SolanaConfig {
8
+ export function validateEnvironment(): AppConfig {
7
9
  const privateKey = process.env.SOLANA_PRIVATE_KEY;
8
10
  if (!privateKey) {
9
11
  throw new Error("Missing required env: SOLANA_PRIVATE_KEY (base58 encoded, standard Solana format)");
10
12
  }
11
13
  const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
12
- return { privateKey, rpcUrl };
14
+ const wayfindApiKey = process.env.WAYFIND_API_KEY || "e1ee8520-305a-49b5-a2de-3e1a7e6078c0";
15
+ const wayfindApiUrl = process.env.WAYFIND_API_URL || "https://o3qftki5dtnlhqlrtvswt336bq0mwdye.lambda-url.ap-southeast-1.on.aws";
16
+ return { privateKey, rpcUrl, wayfindApiKey, wayfindApiUrl };
13
17
  }
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import { SolanaMcpTools } from "./mcp";
5
+ import { McpTools } from "./mcp";
6
6
  import { Agent } from "./agent";
7
7
 
8
8
  function createMcpServer(agent: Agent) {
@@ -11,7 +11,7 @@ function createMcpServer(agent: Agent) {
11
11
  version: "0.1.0",
12
12
  });
13
13
 
14
- for (const [_key, tool] of Object.entries(SolanaMcpTools)) {
14
+ for (const [_key, tool] of Object.entries(McpTools)) {
15
15
  server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {
16
16
  try {
17
17
  const result = await tool.handler(agent, params);
package/src/mcp/index.ts CHANGED
@@ -1,6 +1,16 @@
1
1
  import type { McpTool } from "../types";
2
2
  import { GetWalletAddressTool } from "./solana/get_wallet_address_tool";
3
+ import { WayfindGetTokensTool } from "./wayfind/get_tokens_tool";
4
+ import { WayfindGetTokenizedStocksTool } from "./wayfind/get_tokenized_stocks_tool";
5
+ import { WayfindGetRiskProfileTool } from "./wayfind/get_risk_profile_tool";
6
+ import { WayfindGetMarketOverviewTool } from "./wayfind/get_market_overview_tool";
7
+ import { WayfindGetPreIpoTool } from "./wayfind/get_pre_ipo_tool";
3
8
 
4
- export const SolanaMcpTools: Record<string, McpTool> = {
5
- GetWalletAddressTool,
9
+ export const McpTools: Record<string, McpTool> = {
10
+ SolanaGetWalletAddress: GetWalletAddressTool,
11
+ WayfindGetTokens: WayfindGetTokensTool,
12
+ WayfindGetTokenizedStocks: WayfindGetTokenizedStocksTool,
13
+ WayfindGetRiskProfile: WayfindGetRiskProfileTool,
14
+ WayfindGetMarketOverview: WayfindGetMarketOverviewTool,
15
+ WayfindGetPreIpo: WayfindGetPreIpoTool,
6
16
  };
@@ -0,0 +1,11 @@
1
+ import { Agent } from "../../agent";
2
+ import type { McpTool } from "../../types";
3
+
4
+ export const WayfindGetMarketOverviewTool: McpTool = {
5
+ name: "wayfind_get_market_overview",
6
+ description: "Get market overview including total market cap, 24h volume, gainers, losers, and trending tokens",
7
+ schema: {},
8
+ handler: async (agent: Agent, _input: Record<string, any>) => {
9
+ return agent.wayfindFetch("/market-overview");
10
+ },
11
+ };
@@ -0,0 +1,11 @@
1
+ import { Agent } from "../../agent";
2
+ import type { McpTool } from "../../types";
3
+
4
+ export const WayfindGetPreIpoTool: McpTool = {
5
+ name: "wayfind_get_pre_ipo",
6
+ description: "List pre-IPO markets with mark prices and valuations",
7
+ schema: {},
8
+ handler: async (agent: Agent, _input: Record<string, any>) => {
9
+ return agent.wayfindFetch("/pre-ipo");
10
+ },
11
+ };
@@ -0,0 +1,11 @@
1
+ import { Agent } from "../../agent";
2
+ import type { McpTool } from "../../types";
3
+
4
+ export const WayfindGetRiskProfileTool: McpTool = {
5
+ name: "wayfind_get_risk_profile",
6
+ description: "Get the user's portfolio risk profile including overall score, label, and answers",
7
+ schema: {},
8
+ handler: async (agent: Agent, _input: Record<string, any>) => {
9
+ return agent.wayfindFetch("/risk-profile");
10
+ },
11
+ };
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ import { Agent } from "../../agent";
3
+ import type { McpTool } from "../../types";
4
+
5
+ export const WayfindGetTokenizedStocksTool: McpTool = {
6
+ name: "wayfind_get_tokenized_stocks",
7
+ description: "Get all tokenized versions of a stock ticker across blockchains (e.g. 'AAPL' returns AAPL on Solana, Ethereum, etc.)",
8
+ schema: {
9
+ ticker: z.string().describe("Stock ticker symbol (e.g., 'AAPL', 'GOOG', 'TSLA')"),
10
+ },
11
+ handler: async (agent: Agent, input: Record<string, any>) => {
12
+ return agent.wayfindFetch(`/tokens/${encodeURIComponent(input.ticker)}`);
13
+ },
14
+ };
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ import { Agent } from "../../agent";
3
+ import type { McpTool } from "../../types";
4
+
5
+ export const WayfindGetTokensTool: McpTool = {
6
+ name: "wayfind_get_tokens",
7
+ description: "List all tokenized stocks with prices and market data",
8
+ schema: {
9
+ chain: z.string().optional().describe("Filter by blockchain (e.g., 'solana', 'ethereum')"),
10
+ },
11
+ handler: async (agent: Agent, input: Record<string, any>) => {
12
+ return agent.wayfindFetch("/tokens", input?.chain ? { chain: input.chain } : undefined);
13
+ },
14
+ };