freeturtle 0.1.14 → 0.1.16

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 (48) hide show
  1. package/README.md +79 -59
  2. package/dist/bin/freeturtle.js +10 -2
  3. package/dist/bin/freeturtle.js.map +1 -1
  4. package/dist/src/cli/connect-gmail.d.ts +6 -0
  5. package/dist/src/cli/connect-gmail.js +128 -0
  6. package/dist/src/cli/connect-gmail.js.map +1 -0
  7. package/dist/src/cli/connection-tests.d.ts +4 -0
  8. package/dist/src/cli/connection-tests.js +10 -0
  9. package/dist/src/cli/connection-tests.js.map +1 -1
  10. package/dist/src/cli/init.js +51 -2
  11. package/dist/src/cli/init.js.map +1 -1
  12. package/dist/src/cli/webhooks.js +3 -0
  13. package/dist/src/cli/webhooks.js.map +1 -1
  14. package/dist/src/daemon.js +37 -4
  15. package/dist/src/daemon.js.map +1 -1
  16. package/dist/src/heartbeat.js +3 -1
  17. package/dist/src/heartbeat.js.map +1 -1
  18. package/dist/src/modules/gmail/client.d.ts +62 -0
  19. package/dist/src/modules/gmail/client.js +144 -0
  20. package/dist/src/modules/gmail/client.js.map +1 -0
  21. package/dist/src/modules/gmail/index.d.ts +9 -0
  22. package/dist/src/modules/gmail/index.js +45 -0
  23. package/dist/src/modules/gmail/index.js.map +1 -0
  24. package/dist/src/modules/gmail/tools.d.ts +2 -0
  25. package/dist/src/modules/gmail/tools.js +70 -0
  26. package/dist/src/modules/gmail/tools.js.map +1 -0
  27. package/dist/src/modules/loader.js +6 -1
  28. package/dist/src/modules/loader.js.map +1 -1
  29. package/dist/src/modules/onchain/chains.d.ts +12 -0
  30. package/dist/src/modules/onchain/chains.js +83 -0
  31. package/dist/src/modules/onchain/chains.js.map +1 -0
  32. package/dist/src/modules/onchain/client.js +1 -1
  33. package/dist/src/modules/onchain/client.js.map +1 -1
  34. package/dist/src/modules/onchain/index.d.ts +4 -0
  35. package/dist/src/modules/onchain/index.js +32 -4
  36. package/dist/src/modules/onchain/index.js.map +1 -1
  37. package/dist/src/modules/onchain/portfolio.d.ts +3 -0
  38. package/dist/src/modules/onchain/portfolio.js +180 -0
  39. package/dist/src/modules/onchain/portfolio.js.map +1 -0
  40. package/dist/src/modules/onchain/taskboard.d.ts +3 -0
  41. package/dist/src/modules/onchain/taskboard.js +532 -0
  42. package/dist/src/modules/onchain/taskboard.js.map +1 -0
  43. package/dist/src/modules/onchain/tools.js +1 -1
  44. package/dist/src/modules/onchain/tools.js.map +1 -1
  45. package/dist/src/oauth/google.d.ts +23 -0
  46. package/dist/src/oauth/google.js +110 -0
  47. package/dist/src/oauth/google.js.map +1 -0
  48. package/package.json +3 -1
@@ -0,0 +1,45 @@
1
+ import { createGoogleOAuth2Client, } from "../../oauth/google.js";
2
+ import { GmailClient } from "./client.js";
3
+ import { gmailTools } from "./tools.js";
4
+ export class GmailModule {
5
+ name = "gmail";
6
+ description = "Read and send emails via Gmail.";
7
+ client;
8
+ async initialize(_config, env) {
9
+ const clientId = env.GOOGLE_CLIENT_ID;
10
+ const clientSecret = env.GOOGLE_CLIENT_SECRET;
11
+ const refreshToken = env.GOOGLE_GMAIL_REFRESH_TOKEN;
12
+ if (!clientId || !clientSecret || !refreshToken) {
13
+ throw new Error("Gmail module requires GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and GOOGLE_GMAIL_REFRESH_TOKEN");
14
+ }
15
+ const creds = { clientId, clientSecret, refreshToken };
16
+ const auth = createGoogleOAuth2Client(creds);
17
+ this.client = new GmailClient(auth);
18
+ }
19
+ getTools() {
20
+ return gmailTools;
21
+ }
22
+ async executeTool(name, input) {
23
+ switch (name) {
24
+ case "gmail_read_inbox": {
25
+ const messages = await this.client.listMessages(undefined, input.max_results);
26
+ return JSON.stringify(messages);
27
+ }
28
+ case "gmail_read_email": {
29
+ const message = await this.client.getMessage(input.id);
30
+ return JSON.stringify(message);
31
+ }
32
+ case "gmail_send_email": {
33
+ const result = await this.client.sendMessage(input.to, input.subject, input.body);
34
+ return JSON.stringify(result);
35
+ }
36
+ case "gmail_search": {
37
+ const results = await this.client.searchMessages(input.query, input.max_results);
38
+ return JSON.stringify(results);
39
+ }
40
+ default:
41
+ throw new Error(`Unknown gmail tool: ${name}`);
42
+ }
43
+ }
44
+ }
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/gmail/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,GAEzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,OAAO,WAAW;IACtB,IAAI,GAAG,OAAO,CAAC;IACf,WAAW,GAAG,iCAAiC,CAAC;IAExC,MAAM,CAAe;IAE7B,KAAK,CAAC,UAAU,CACd,OAAgC,EAChC,GAA2B;QAE3B,MAAM,QAAQ,GAAG,GAAG,CAAC,gBAAgB,CAAC;QACtC,MAAM,YAAY,GAAG,GAAG,CAAC,oBAAoB,CAAC;QAC9C,MAAM,YAAY,GAAG,GAAG,CAAC,0BAA0B,CAAC;QAEpD,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CACb,8FAA8F,CAC/F,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAA2B,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;QAC/E,MAAM,IAAI,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACN,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,IAAY,EACZ,KAA8B;QAE9B,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAC7C,SAAS,EACT,KAAK,CAAC,WAAiC,CACxC,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,EAAY,CAAC,CAAC;gBACjE,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAC1C,KAAK,CAAC,EAAY,EAClB,KAAK,CAAC,OAAiB,EACvB,KAAK,CAAC,IAAc,CACrB,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;YACD,KAAK,cAAc,CAAC,CAAC,CAAC;gBACpB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAC9C,KAAK,CAAC,KAAe,EACrB,KAAK,CAAC,WAAiC,CACxC,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YACD;gBACE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const gmailTools: ToolDefinition[];
@@ -0,0 +1,70 @@
1
+ export const gmailTools = [
2
+ {
3
+ name: "gmail_read_inbox",
4
+ description: "Read recent emails from the inbox. Returns a list of email summaries (id, from, subject, date, snippet).",
5
+ input_schema: {
6
+ type: "object",
7
+ properties: {
8
+ max_results: {
9
+ type: "number",
10
+ description: "Maximum number of emails to return (default: 10)",
11
+ },
12
+ },
13
+ },
14
+ },
15
+ {
16
+ name: "gmail_read_email",
17
+ description: "Read the full content of a specific email by its ID. Returns the complete email with headers and body.",
18
+ input_schema: {
19
+ type: "object",
20
+ properties: {
21
+ id: {
22
+ type: "string",
23
+ description: "The Gmail message ID",
24
+ },
25
+ },
26
+ required: ["id"],
27
+ },
28
+ },
29
+ {
30
+ name: "gmail_send_email",
31
+ description: "Send an email from the CEO's Gmail account.",
32
+ input_schema: {
33
+ type: "object",
34
+ properties: {
35
+ to: {
36
+ type: "string",
37
+ description: "Recipient email address",
38
+ },
39
+ subject: {
40
+ type: "string",
41
+ description: "Email subject line",
42
+ },
43
+ body: {
44
+ type: "string",
45
+ description: "Email body (plain text)",
46
+ },
47
+ },
48
+ required: ["to", "subject", "body"],
49
+ },
50
+ },
51
+ {
52
+ name: "gmail_search",
53
+ description: "Search emails using Gmail search syntax (e.g. 'from:alice subject:meeting after:2024/01/01'). Returns matching email summaries.",
54
+ input_schema: {
55
+ type: "object",
56
+ properties: {
57
+ query: {
58
+ type: "string",
59
+ description: "Gmail search query",
60
+ },
61
+ max_results: {
62
+ type: "number",
63
+ description: "Maximum number of results (default: 10)",
64
+ },
65
+ },
66
+ required: ["query"],
67
+ },
68
+ },
69
+ ];
70
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/modules/gmail/tools.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAqB;IAC1C;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,0GAA0G;QACvH,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kDAAkD;iBAChE;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,wGAAwG;QACrH,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,EAAE,EAAE;oBACF,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sBAAsB;iBACpC;aACF;YACD,QAAQ,EAAE,CAAC,IAAI,CAAC;SACjB;KACF;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,6CAA6C;QAC1D,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,EAAE,EAAE;oBACF,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yBAAyB;iBACvC;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oBAAoB;iBAClC;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yBAAyB;iBACvC;aACF;YACD,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC;SACpC;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,iIAAiI;QAC9I,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oBAAoB;iBAClC;gBACD,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yCAAyC;iBACvD;aACF;YACD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB;KACF;CACF,CAAC"}
@@ -3,11 +3,13 @@ import { DatabaseModule } from "./database/index.js";
3
3
  import { GitHubModule } from "./github/index.js";
4
4
  import { OnchainModule } from "./onchain/index.js";
5
5
  import { XmtpModule } from "./xmtp/index.js";
6
+ import { GmailModule } from "./gmail/index.js";
6
7
  import { WorkspaceModule } from "./workspace/index.js";
7
8
  const MODULE_MAP = {
8
9
  farcaster: FarcasterModule,
9
10
  database: DatabaseModule,
10
11
  github: GitHubModule,
12
+ gmail: GmailModule,
11
13
  onchain: OnchainModule,
12
14
  xmtp: XmtpModule,
13
15
  };
@@ -35,7 +37,10 @@ export async function loadModules(config, env, logger, policy, dir) {
35
37
  }
36
38
  try {
37
39
  const mod = new ModuleClass();
38
- await mod.initialize(moduleConfig, env, { policy });
40
+ const cfg = { ...moduleConfig };
41
+ if (dir)
42
+ cfg._workspaceDir = dir;
43
+ await mod.initialize(cfg, env, { policy });
39
44
  modules.push(mod);
40
45
  }
41
46
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/modules/loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,UAAU,GAA+C;IAC7D,SAAS,EAAE,eAAe;IAC1B,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,aAAa;IACtB,IAAI,EAAE,UAAU;CACjB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAwB,EACxB,GAA2B,EAC3B,MAAe,EACf,MAAqB,EACrB,GAAY;IAEZ,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,qFAAqF;IACrF,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;YACxC,MAAM,SAAS,CAAC,UAAU,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACjE,MAAM,EAAE,KAAK,CAAC,0CAA0C,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC,YAAY,CAAC,OAAO;YAAE,SAAS;QAEpC,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,EAAE,IAAI,CAAC,mBAAmB,IAAI,aAAa,CAAC,CAAC;YACnD,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,GAAG,CAAC,UAAU,CAClB,YAAkD,EAClD,GAAG,EACH,EAAE,MAAM,EAAE,CACX,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACjE,MAAM,EAAE,KAAK,CAAC,WAAW,IAAI,2BAA2B,GAAG,aAAa,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/modules/loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,UAAU,GAA+C;IAC7D,SAAS,EAAE,eAAe;IAC1B,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,WAAW;IAClB,OAAO,EAAE,aAAa;IACtB,IAAI,EAAE,UAAU;CACjB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAwB,EACxB,GAA2B,EAC3B,MAAe,EACf,MAAqB,EACrB,GAAY;IAEZ,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,qFAAqF;IACrF,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;YACxC,MAAM,SAAS,CAAC,UAAU,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACjE,MAAM,EAAE,KAAK,CAAC,0CAA0C,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC,YAAY,CAAC,OAAO;YAAE,SAAS;QAEpC,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,EAAE,IAAI,CAAC,mBAAmB,IAAI,aAAa,CAAC,CAAC;YACnD,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,EAAE,GAAI,YAAmD,EAAE,CAAC;YACxE,IAAI,GAAG;gBAAE,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC;YACjC,MAAM,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACjE,MAAM,EAAE,KAAK,CAAC,WAAW,IAAI,2BAA2B,GAAG,aAAa,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type Chain, type PublicClient, type WalletClient } from "viem";
2
+ import { type PrivateKeyAccount } from "viem/accounts";
3
+ export interface TaskChainClients {
4
+ chain: Chain;
5
+ account: PrivateKeyAccount;
6
+ walletClient: WalletClient;
7
+ publicClient: PublicClient;
8
+ }
9
+ export declare function getTaskChain(env: Record<string, string>): Chain;
10
+ export declare function getCeoAccount(env: Record<string, string>): PrivateKeyAccount;
11
+ export declare function getClients(env: Record<string, string>): TaskChainClients;
12
+ export declare function explorerTxUrl(chain: Chain, hash: string): string;
@@ -0,0 +1,83 @@
1
+ import { defineChain, createPublicClient, createWalletClient, http, } from "viem";
2
+ import { privateKeyToAccount } from "viem/accounts";
3
+ const KNOWN_CHAINS = {
4
+ 46630: defineChain({
5
+ id: 46630,
6
+ name: "Robinhood Chain Testnet",
7
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
8
+ rpcUrls: {
9
+ default: { http: ["https://rpc.testnet.chain.robinhood.com"] },
10
+ },
11
+ blockExplorers: {
12
+ default: {
13
+ name: "Explorer",
14
+ url: "https://explorer.testnet.chain.robinhood.com",
15
+ },
16
+ },
17
+ }),
18
+ 421614: defineChain({
19
+ id: 421614,
20
+ name: "Arbitrum Sepolia",
21
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
22
+ rpcUrls: {
23
+ default: { http: ["https://sepolia-rollup.arbitrum.io/rpc"] },
24
+ },
25
+ blockExplorers: {
26
+ default: { name: "Arbiscan", url: "https://sepolia.arbiscan.io" },
27
+ },
28
+ }),
29
+ 8453: defineChain({
30
+ id: 8453,
31
+ name: "Base",
32
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
33
+ rpcUrls: { default: { http: ["https://mainnet.base.org"] } },
34
+ blockExplorers: {
35
+ default: { name: "Basescan", url: "https://basescan.org" },
36
+ },
37
+ }),
38
+ };
39
+ export function getTaskChain(env) {
40
+ const chainId = parseInt(env.TASK_CHAIN_ID || "0");
41
+ const rpcOverride = env.TASK_CHAIN_RPC;
42
+ let chain = KNOWN_CHAINS[chainId];
43
+ if (!chain && rpcOverride) {
44
+ chain = defineChain({
45
+ id: chainId,
46
+ name: `Chain ${chainId}`,
47
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
48
+ rpcUrls: { default: { http: [rpcOverride] } },
49
+ });
50
+ }
51
+ if (!chain)
52
+ throw new Error(`Unknown chain ID ${chainId} and no TASK_CHAIN_RPC set`);
53
+ if (rpcOverride) {
54
+ chain = { ...chain, rpcUrls: { default: { http: [rpcOverride] } } };
55
+ }
56
+ return chain;
57
+ }
58
+ export function getCeoAccount(env) {
59
+ const key = env.CEO_PRIVATE_KEY;
60
+ if (!key)
61
+ throw new Error("CEO_PRIVATE_KEY not set");
62
+ return privateKeyToAccount(key);
63
+ }
64
+ export function getClients(env) {
65
+ const chain = getTaskChain(env);
66
+ const account = getCeoAccount(env);
67
+ return {
68
+ chain,
69
+ account,
70
+ walletClient: createWalletClient({
71
+ account,
72
+ chain,
73
+ transport: http(),
74
+ }),
75
+ publicClient: createPublicClient({ chain, transport: http() }),
76
+ };
77
+ }
78
+ export function explorerTxUrl(chain, hash) {
79
+ return chain.blockExplorers?.default?.url
80
+ ? `${chain.blockExplorers.default.url}/tx/${hash}`
81
+ : hash;
82
+ }
83
+ //# sourceMappingURL=chains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../../../../src/modules/onchain/chains.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,7 @@ export class OnchainClient {
28
28
  }
29
29
  async getTransactions(address, limit = 10) {
30
30
  if (!this.basescanKey) {
31
- return [{ error: "BASESCAN_API_KEY not set, cannot fetch transactions" }];
31
+ return [{ error: "BLOCK_EXPLORER_API_KEY not set, cannot fetch transactions" }];
32
32
  }
33
33
  const url = `https://api.basescan.org/api?module=account&action=txlist&address=${address}&startblock=0&endblock=99999999&page=1&offset=${limit}&sort=desc&apikey=${this.basescanKey}`;
34
34
  const res = await fetch(url);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/modules/onchain/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,MAAM,OAAO,aAAa;IACxB,8DAA8D;IACtD,MAAM,CAAM;IACZ,WAAW,CAAU;IAE7B,YAAY,MAAc,EAAE,WAAoB;QAC9C,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC;YAC/B,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;SACxB,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,OAAe,EACf,GAAc,EACd,YAAoB,EACpB,IAAgB;QAEhB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC5C,OAAO,EAAE,OAAwB;YACjC,GAAG;YACH,YAAY;YACZ,IAAI,EAAE,IAAI,IAAI,EAAE;SACjB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe;QAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YAC3C,OAAO,EAAE,OAAwB;SAClC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,OAAe,EACf,KAAK,GAAG,EAAE;QAEV,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,CAAC,EAAE,KAAK,EAAE,qDAAqD,EAAE,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,GAAG,GAAG,qEAAqE,OAAO,iDAAiD,KAAK,qBAAqB,IAAI,CAAC,WAAW,EAAE,CAAC;QACtL,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAE7B,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACtC,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,EAAE,EAAE,EAAE,CAAC,EAAE;YACT,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,SAAS,EAAE,EAAE,CAAC,SAAS;YACvB,YAAY,EAAE,EAAE,CAAC,YAAY;SAC9B,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/modules/onchain/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,MAAM,OAAO,aAAa;IACxB,8DAA8D;IACtD,MAAM,CAAM;IACZ,WAAW,CAAU;IAE7B,YAAY,MAAc,EAAE,WAAoB;QAC9C,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC;YAC/B,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;SACxB,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,OAAe,EACf,GAAc,EACd,YAAoB,EACpB,IAAgB;QAEhB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC5C,OAAO,EAAE,OAAwB;YACjC,GAAG;YACH,YAAY;YACZ,IAAI,EAAE,IAAI,IAAI,EAAE;SACjB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe;QAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YAC3C,OAAO,EAAE,OAAwB;SAClC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,OAAe,EACf,KAAK,GAAG,EAAE;QAEV,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,CAAC,EAAE,KAAK,EAAE,2DAA2D,EAAE,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,GAAG,GAAG,qEAAqE,OAAO,iDAAiD,KAAK,qBAAqB,IAAI,CAAC,WAAW,EAAE,CAAC;QACtL,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAE7B,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACtC,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,EAAE,EAAE,EAAE,CAAC,EAAE;YACT,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,SAAS,EAAE,EAAE,CAAC,SAAS;YACvB,YAAY,EAAE,EAAE,CAAC,YAAY;SAC9B,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
@@ -5,6 +5,10 @@ export declare class OnchainModule implements FreeTurtleModule {
5
5
  description: string;
6
6
  private client;
7
7
  private policy?;
8
+ private env;
9
+ private hasWriteAccess;
10
+ private hasTaskboard;
11
+ private workspaceDir?;
8
12
  initialize(_config: Record<string, unknown>, env: Record<string, string>, options?: {
9
13
  policy?: PolicyConfig;
10
14
  }): Promise<void>;
@@ -2,22 +2,41 @@ import { assertOnchainScopeAllowed } from "../../policy.js";
2
2
  import { withRetry } from "../../reliability.js";
3
3
  import { OnchainClient } from "./client.js";
4
4
  import { onchainTools } from "./tools.js";
5
+ import { taskboardTools, executeTaskboardTool, } from "./taskboard.js";
6
+ import { portfolioTools, executePortfolioTool, } from "./portfolio.js";
5
7
  export class OnchainModule {
6
8
  name = "onchain";
7
9
  description = "Read smart contracts, balances, and transactions on Base.";
8
10
  client;
9
11
  policy;
12
+ env;
13
+ hasWriteAccess = false;
14
+ hasTaskboard = false;
15
+ workspaceDir;
10
16
  async initialize(_config, env, options) {
11
17
  const rpcUrl = env.RPC_URL;
12
18
  if (!rpcUrl)
13
19
  throw new Error("Onchain module requires RPC_URL");
14
- this.client = new OnchainClient(rpcUrl, env.BASESCAN_API_KEY);
20
+ this.client = new OnchainClient(rpcUrl, env.BLOCK_EXPLORER_API_KEY);
15
21
  this.policy = options?.policy;
22
+ this.env = env;
23
+ this.workspaceDir = _config._workspaceDir;
24
+ this.hasWriteAccess = !!env.CEO_PRIVATE_KEY && !!env.TASK_CHAIN_ID;
25
+ this.hasTaskboard =
26
+ this.hasWriteAccess && !!env.TASK_CONTRACT_ADDRESS;
16
27
  }
17
28
  getTools() {
18
- return onchainTools;
29
+ const tools = [...onchainTools];
30
+ if (this.hasTaskboard) {
31
+ tools.push(...taskboardTools);
32
+ }
33
+ if (this.hasWriteAccess) {
34
+ tools.push(...portfolioTools);
35
+ }
36
+ return tools;
19
37
  }
20
38
  async executeTool(name, input) {
39
+ // Existing read-only tools
21
40
  switch (name) {
22
41
  case "read_contract": {
23
42
  assertOnchainScopeAllowed(this.policy, input.address, input.function_name);
@@ -32,9 +51,18 @@ export class OnchainModule {
32
51
  const txs = await withRetry(() => this.client.getTransactions(input.address, input.limit ?? 10));
33
52
  return JSON.stringify(txs);
34
53
  }
35
- default:
36
- throw new Error(`Unknown onchain tool: ${name}`);
37
54
  }
55
+ // TaskBoard tools
56
+ if (this.hasTaskboard &&
57
+ taskboardTools.some((t) => t.name === name)) {
58
+ return executeTaskboardTool(name, input, this.env, this.workspaceDir);
59
+ }
60
+ // Portfolio tools
61
+ if (this.hasWriteAccess &&
62
+ portfolioTools.some((t) => t.name === name)) {
63
+ return executePortfolioTool(name, input, this.env);
64
+ }
65
+ throw new Error(`Unknown onchain tool: ${name}`);
38
66
  }
39
67
  }
40
68
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/onchain/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,OAAO,aAAa;IACxB,IAAI,GAAG,SAAS,CAAC;IACjB,WAAW,GAAG,2DAA2D,CAAC;IAElE,MAAM,CAAiB;IACvB,MAAM,CAAgB;IAE9B,KAAK,CAAC,UAAU,CACd,OAAgC,EAChC,GAA2B,EAC3B,OAAmC;QAEnC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAChE,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAChC,CAAC;IAED,QAAQ;QACN,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,IAAY,EACZ,KAA8B;QAE9B,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,yBAAyB,CACvB,IAAI,CAAC,MAAM,EACX,KAAK,CAAC,OAAiB,EACvB,KAAK,CAAC,aAAuB,CAC9B,CAAC;gBACF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAClC,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,KAAK,CAAC,OAAiB,EACvB,KAAK,CAAC,GAAgB,EACtB,KAAK,CAAC,aAAuB,EAC7B,KAAK,CAAC,IAA6B,CACpC,CACF,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CACnC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,OAAiB,CAAC,CAChD,CAAC;gBACF,OAAO,GAAG,OAAO,MAAM,CAAC;YAC1B,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAC/B,IAAI,CAAC,MAAM,CAAC,eAAe,CACzB,KAAK,CAAC,OAAiB,EACtB,KAAK,CAAC,KAAgB,IAAI,EAAE,CAC9B,CACF,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;YACD;gBACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/onchain/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const portfolioTools: ToolDefinition[];
3
+ export declare function executePortfolioTool(name: string, input: Record<string, unknown>, env: Record<string, string>): Promise<string>;
@@ -0,0 +1,180 @@
1
+ import { parseUnits, formatUnits, formatEther } from "viem";
2
+ import { getClients, explorerTxUrl } from "./chains.js";
3
+ const ERC20_ABI = [
4
+ {
5
+ name: "transfer",
6
+ type: "function",
7
+ stateMutability: "nonpayable",
8
+ inputs: [
9
+ { name: "to", type: "address" },
10
+ { name: "amount", type: "uint256" },
11
+ ],
12
+ outputs: [{ name: "", type: "bool" }],
13
+ },
14
+ {
15
+ name: "balanceOf",
16
+ type: "function",
17
+ stateMutability: "view",
18
+ inputs: [{ name: "account", type: "address" }],
19
+ outputs: [{ name: "", type: "uint256" }],
20
+ },
21
+ {
22
+ name: "decimals",
23
+ type: "function",
24
+ stateMutability: "view",
25
+ inputs: [],
26
+ outputs: [{ name: "", type: "uint8" }],
27
+ },
28
+ {
29
+ name: "symbol",
30
+ type: "function",
31
+ stateMutability: "view",
32
+ inputs: [],
33
+ outputs: [{ name: "", type: "string" }],
34
+ },
35
+ ];
36
+ export const portfolioTools = [
37
+ {
38
+ name: "transfer_token",
39
+ description: "Transfer ERC20 tokens from the CEO wallet to another address. Used to execute portfolio strategies by moving tokenized assets (stock tokens, stablecoins, etc.). Always check token balance before transferring.",
40
+ input_schema: {
41
+ type: "object",
42
+ properties: {
43
+ token_address: {
44
+ type: "string",
45
+ description: "Contract address of the ERC20 token",
46
+ },
47
+ to_address: {
48
+ type: "string",
49
+ description: "Recipient address",
50
+ },
51
+ amount: {
52
+ type: "string",
53
+ description: 'Amount in human-readable units (e.g. "2.5" for 2.5 tokens)',
54
+ },
55
+ },
56
+ required: ["token_address", "to_address", "amount"],
57
+ },
58
+ },
59
+ {
60
+ name: "get_token_balance",
61
+ description: "Check the balance of an ERC20 token (stock tokens, stablecoins, etc.) for any address. Defaults to the CEO wallet if no address specified.",
62
+ input_schema: {
63
+ type: "object",
64
+ properties: {
65
+ token_address: {
66
+ type: "string",
67
+ description: "Contract address of the ERC20 token",
68
+ },
69
+ wallet_address: {
70
+ type: "string",
71
+ description: "Address to check. Defaults to CEO wallet.",
72
+ },
73
+ },
74
+ required: ["token_address"],
75
+ },
76
+ },
77
+ {
78
+ name: "get_ceo_wallet_balance",
79
+ description: "Check the CEO wallet's native ETH balance on the task chain.",
80
+ input_schema: {
81
+ type: "object",
82
+ properties: {},
83
+ },
84
+ },
85
+ ];
86
+ export async function executePortfolioTool(name, input, env) {
87
+ try {
88
+ switch (name) {
89
+ case "transfer_token":
90
+ return await transferToken(input.token_address, input.to_address, input.amount, env);
91
+ case "get_token_balance":
92
+ return await getTokenBalance(input.token_address, input.wallet_address, env);
93
+ case "get_ceo_wallet_balance":
94
+ return await getCeoWalletBalance(env);
95
+ default:
96
+ throw new Error(`Unknown portfolio tool: ${name}`);
97
+ }
98
+ }
99
+ catch (error) {
100
+ const msg = error instanceof Error
101
+ ? error.shortMessage || error.message
102
+ : "Unknown error";
103
+ return JSON.stringify({ error: true, message: `Failed: ${msg}` });
104
+ }
105
+ }
106
+ async function transferToken(tokenAddress, toAddress, amount, env) {
107
+ const { chain, account, walletClient, publicClient } = getClients(env);
108
+ const [decimals, symbol] = await Promise.all([
109
+ publicClient.readContract({
110
+ address: tokenAddress,
111
+ abi: ERC20_ABI,
112
+ functionName: "decimals",
113
+ }),
114
+ publicClient.readContract({
115
+ address: tokenAddress,
116
+ abi: ERC20_ABI,
117
+ functionName: "symbol",
118
+ }),
119
+ ]);
120
+ const parsedAmount = parseUnits(amount, decimals);
121
+ const hash = await walletClient.writeContract({
122
+ chain,
123
+ account,
124
+ address: tokenAddress,
125
+ abi: ERC20_ABI,
126
+ functionName: "transfer",
127
+ args: [toAddress, parsedAmount],
128
+ });
129
+ await publicClient.waitForTransactionReceipt({ hash });
130
+ return JSON.stringify({
131
+ token: symbol,
132
+ tokenAddress,
133
+ amount,
134
+ to: toAddress,
135
+ txHash: hash,
136
+ explorerUrl: explorerTxUrl(chain, hash),
137
+ chain: chain.name,
138
+ });
139
+ }
140
+ async function getTokenBalance(tokenAddress, walletAddress, env) {
141
+ const { chain, publicClient, account } = getClients(env);
142
+ const address = (walletAddress || account.address);
143
+ const [balance, decimals, symbol] = await Promise.all([
144
+ publicClient.readContract({
145
+ address: tokenAddress,
146
+ abi: ERC20_ABI,
147
+ functionName: "balanceOf",
148
+ args: [address],
149
+ }),
150
+ publicClient.readContract({
151
+ address: tokenAddress,
152
+ abi: ERC20_ABI,
153
+ functionName: "decimals",
154
+ }),
155
+ publicClient.readContract({
156
+ address: tokenAddress,
157
+ abi: ERC20_ABI,
158
+ functionName: "symbol",
159
+ }),
160
+ ]);
161
+ return JSON.stringify({
162
+ token: symbol,
163
+ tokenAddress,
164
+ balance: formatUnits(balance, decimals),
165
+ wallet: address,
166
+ chain: chain.name,
167
+ });
168
+ }
169
+ async function getCeoWalletBalance(env) {
170
+ const { chain, publicClient, account } = getClients(env);
171
+ const balance = await publicClient.getBalance({
172
+ address: account.address,
173
+ });
174
+ return JSON.stringify({
175
+ address: account.address,
176
+ balanceEth: formatEther(balance),
177
+ chain: chain.name,
178
+ });
179
+ }
180
+ //# sourceMappingURL=portfolio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portfolio.js","sourceRoot":"","sources":["../../../../src/modules/onchain/portfolio.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const taskboardTools: ToolDefinition[];
3
+ export declare function executeTaskboardTool(name: string, input: Record<string, unknown>, env: Record<string, string>, workspaceDir?: string): Promise<string>;