From 025da2f530996c475590c749d28f65471df8be7f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 12:22:07 +0000 Subject: [PATCH 1/3] feat: implement 1inch balance plugin with getAggregatedBalancesAndAllowances tool Co-Authored-By: Alfonso Gomez Jordana Manas --- typescript/package.json | 3 + .../plugins/1inch-balance/package.json | 32 +++++++++++ .../1inch-balance/src/balance.service.ts | 42 ++++++++++++++ .../plugins/1inch-balance/src/index.ts | 3 + .../plugins/1inch-balance/src/parameters.ts | 11 ++++ .../plugins/1inch-balance/src/types.ts | 13 +++++ .../plugins/1inch-balance/tsconfig.json | 6 ++ .../plugins/1inch-balance/tsup.config.ts | 11 ++++ typescript/pnpm-lock.yaml | 57 +++++++++++++++++++ 9 files changed, 178 insertions(+) create mode 100644 typescript/packages/plugins/1inch-balance/package.json create mode 100644 typescript/packages/plugins/1inch-balance/src/balance.service.ts create mode 100644 typescript/packages/plugins/1inch-balance/src/index.ts create mode 100644 typescript/packages/plugins/1inch-balance/src/parameters.ts create mode 100644 typescript/packages/plugins/1inch-balance/src/types.ts create mode 100644 typescript/packages/plugins/1inch-balance/tsconfig.json create mode 100644 typescript/packages/plugins/1inch-balance/tsup.config.ts diff --git a/typescript/package.json b/typescript/package.json index dcadac10..a330a9e2 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -24,6 +24,9 @@ "cross-env": "7.0.3", "globals": "15.12.0", "rimraf": "6.0.1", + "@goat-sdk/core": "workspace:*", + "node-fetch": "^3.0.0", + "zod": "^3.0.0", "ts-node": "10.9.2", "tsc-alias": "1.8.10", "tsup": "8.3.5", diff --git a/typescript/packages/plugins/1inch-balance/package.json b/typescript/packages/plugins/1inch-balance/package.json new file mode 100644 index 00000000..cdb06930 --- /dev/null +++ b/typescript/packages/plugins/1inch-balance/package.json @@ -0,0 +1,32 @@ +{ + "name": "@goat-sdk/plugin-1inch-balance", + "version": "0.0.1", + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests", + "lint": "biome check src/" + }, + "sideEffects": false, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "zod": "catalog:" + }, + "peerDependencies": { + "@goat-sdk/core": "workspace:*" + }, + "homepage": "https://ohmygoat.dev", + "repository": { + "type": "git", + "url": "git+https://github.com/goat-sdk/goat.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/goat-sdk/goat/issues" + }, + "keywords": ["ai", "agents", "web3"] +} diff --git a/typescript/packages/plugins/1inch-balance/src/balance.service.ts b/typescript/packages/plugins/1inch-balance/src/balance.service.ts new file mode 100644 index 00000000..264ad9fb --- /dev/null +++ b/typescript/packages/plugins/1inch-balance/src/balance.service.ts @@ -0,0 +1,42 @@ +import { Tool } from "@goat-sdk/core"; +import { GetAggregatedBalancesAndAllowancesParameters } from "./parameters"; +import { AggregatedBalancesAndAllowancesResponse, BalanceServiceParams } from "./types"; + +export class BalanceService { + private readonly baseUrl: string; + private readonly apiKey?: string; + + constructor(params: BalanceServiceParams = {}) { + this.baseUrl = params.baseUrl ?? "https://api.1inch.dev/balance"; + this.apiKey = params.apiKey; + } + + @Tool({ + description: + "Get aggregated balances and allowances for a list of wallet addresses, checking their token balances and allowances for a specific spender address.", + }) + async getAggregatedBalancesAndAllowances( + parameters: GetAggregatedBalancesAndAllowancesParameters, + ): Promise { + const { chain, spender, wallets, filterEmpty } = parameters; + + const url = new URL(`${this.baseUrl}/v1.2/${chain}/aggregatedBalancesAndAllowances/${spender}`); + url.searchParams.append("wallets", wallets.join(",")); + if (filterEmpty !== undefined) { + url.searchParams.append("filterEmpty", String(filterEmpty)); + } + + const response = await fetch(url.toString(), { + headers: { + Accept: "application/json", + ...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }), + }, + }); + + if (!response.ok) { + throw new Error(`Failed to fetch balances: ${response.statusText}`); + } + + return await response.json(); + } +} diff --git a/typescript/packages/plugins/1inch-balance/src/index.ts b/typescript/packages/plugins/1inch-balance/src/index.ts new file mode 100644 index 00000000..c7c4a5fd --- /dev/null +++ b/typescript/packages/plugins/1inch-balance/src/index.ts @@ -0,0 +1,3 @@ +export * from "./balance.service"; +export * from "./parameters"; +export * from "./types"; diff --git a/typescript/packages/plugins/1inch-balance/src/parameters.ts b/typescript/packages/plugins/1inch-balance/src/parameters.ts new file mode 100644 index 00000000..f2548b56 --- /dev/null +++ b/typescript/packages/plugins/1inch-balance/src/parameters.ts @@ -0,0 +1,11 @@ +import { createToolParameters } from "@goat-sdk/core"; +import { z } from "zod"; + +export class GetAggregatedBalancesAndAllowancesParameters extends createToolParameters( + z.object({ + chain: z.number().describe("The chain ID to query balances on"), + spender: z.string().describe("The spender address to check allowances for"), + wallets: z.array(z.string()).describe("List of wallet addresses to check balances for"), + filterEmpty: z.boolean().optional().describe("Whether to filter out empty balances"), + }), +) {} diff --git a/typescript/packages/plugins/1inch-balance/src/types.ts b/typescript/packages/plugins/1inch-balance/src/types.ts new file mode 100644 index 00000000..4b0c0987 --- /dev/null +++ b/typescript/packages/plugins/1inch-balance/src/types.ts @@ -0,0 +1,13 @@ +export interface BalanceServiceParams { + baseUrl?: string; + apiKey?: string; +} + +export interface TokenBalance { + balance: string; + allowance: string; +} + +export interface AggregatedBalancesAndAllowancesResponse { + [tokenAddress: string]: TokenBalance; +} diff --git a/typescript/packages/plugins/1inch-balance/tsconfig.json b/typescript/packages/plugins/1inch-balance/tsconfig.json new file mode 100644 index 00000000..b4ae67c1 --- /dev/null +++ b/typescript/packages/plugins/1inch-balance/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/typescript/packages/plugins/1inch-balance/tsup.config.ts b/typescript/packages/plugins/1inch-balance/tsup.config.ts new file mode 100644 index 00000000..95782742 --- /dev/null +++ b/typescript/packages/plugins/1inch-balance/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts", "src/balance.service.ts", "src/parameters.ts", "src/types.ts"], + format: ["esm", "cjs"], + dts: true, + splitting: true, + sourcemap: true, + clean: true, + target: "es2022", +}); diff --git a/typescript/pnpm-lock.yaml b/typescript/pnpm-lock.yaml index 8eb26fc5..b3f150c7 100644 --- a/typescript/pnpm-lock.yaml +++ b/typescript/pnpm-lock.yaml @@ -71,6 +71,9 @@ importers: '@changesets/cli': specifier: 2.27.10 version: 2.27.10 + '@goat-sdk/core': + specifier: workspace:* + version: link:packages/core '@swc/core': specifier: 1.10.1 version: 1.10.1(@swc/helpers@0.5.15) @@ -83,6 +86,9 @@ importers: globals: specifier: 15.12.0 version: 15.12.0 + node-fetch: + specifier: ^3.0.0 + version: 3.3.2 rimraf: specifier: 6.0.1 version: 6.0.1 @@ -104,6 +110,9 @@ importers: vitest: specifier: 2.1.5 version: 2.1.5(@types/node@22.7.4)(terser@5.37.0) + zod: + specifier: ^3.0.0 + version: 3.24.1 examples/eleven-labs/conversational-agent: dependencies: @@ -886,6 +895,15 @@ importers: specifier: 'catalog:' version: 3.23.8 + packages/plugins/1inch-balance: + dependencies: + '@goat-sdk/core': + specifier: workspace:* + version: link:../../core + zod: + specifier: 'catalog:' + version: 3.23.8 + packages/plugins/allora: dependencies: '@goat-sdk/core': @@ -6665,6 +6683,10 @@ packages: csv-parse@5.6.0: resolution: {integrity: sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + date-and-time@2.4.3: resolution: {integrity: sha512-xkS/imTmsyEdpp9ie5oV5UWolg3XkYWNySbT2W4ESWr6v4V8YrsHbhpk9fIeQcr0NFTnYbQJLXlgU1zrLItysA==} @@ -7200,6 +7222,10 @@ packages: fecha@4.2.3: resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + fetch-h2@3.0.2: resolution: {integrity: sha512-Lo6UPdMKKc9Ond7yjG2vq0mnocspOLh1oV6+XZdtfdexacvMSz5xm3WoQhTAdoR2+UqPlyMNqcqfecipoD+l/A==} engines: {node: '>=12'} @@ -7298,6 +7324,10 @@ packages: resolution: {integrity: sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==} engines: {node: '>= 18'} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + formik@2.2.9: resolution: {integrity: sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==} peerDependencies: @@ -8722,6 +8752,10 @@ packages: encoding: optional: true + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -10920,6 +10954,10 @@ packages: resolution: {integrity: sha512-I661rRsEDxB1rkSVWHw8BC2vR/RIhcatD6BGS1XKaIhdvKQQ8L1oeYRx3XHOnQx5CULYJOoMszqaeQlmbjSxOg==} engines: {node: '>=18.0.0'} + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + web-streams-polyfill@4.0.0-beta.3: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} @@ -19705,6 +19743,8 @@ snapshots: csv-parse@5.6.0: {} + data-uri-to-buffer@4.0.1: {} + date-and-time@2.4.3: {} date-fns@2.30.0: @@ -20341,6 +20381,11 @@ snapshots: fecha@4.2.3: {} + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + fetch-h2@3.0.2: dependencies: '@types/tough-cookie': 4.0.5 @@ -20451,6 +20496,10 @@ snapshots: formdata-node@6.0.3: {} + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + formik@2.2.9(react@18.3.1): dependencies: deepmerge: 2.2.1 @@ -22169,6 +22218,12 @@ snapshots: optionalDependencies: encoding: 0.1.13 + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-forge@1.3.1: {} node-gyp-build@4.8.4: {} @@ -24766,6 +24821,8 @@ snapshots: transitivePeerDependencies: - encoding + web-streams-polyfill@3.3.3: {} + web-streams-polyfill@4.0.0-beta.3: {} web-tree-sitter@0.24.6: {} From 65bf1bf3b20f149f642f9e2b0adb14f71d4c72fc Mon Sep 17 00:00:00 2001 From: Agustin Armellini Fischer Date: Sat, 4 Jan 2025 17:02:46 +0100 Subject: [PATCH 2/3] Fix PR --- goat.code-workspace | 4 ++++ .../plugins/1inch-balance/src/parameters.ts | 11 --------- .../{1inch-balance => 1inch}/package.json | 8 ++++--- .../src/balance.service.ts | 23 ++++++++++--------- .../{1inch-balance => 1inch}/src/index.ts | 0 .../packages/plugins/1inch/src/parameters.ts | 8 +++++++ .../{1inch-balance => 1inch}/src/types.ts | 0 .../{1inch-balance => 1inch}/tsconfig.json | 0 .../{1inch-balance => 1inch}/tsup.config.ts | 0 typescript/pnpm-lock.yaml | 5 +++- 10 files changed, 33 insertions(+), 26 deletions(-) delete mode 100644 typescript/packages/plugins/1inch-balance/src/parameters.ts rename typescript/packages/plugins/{1inch-balance => 1inch}/package.json (79%) rename typescript/packages/plugins/{1inch-balance => 1inch}/src/balance.service.ts (52%) rename typescript/packages/plugins/{1inch-balance => 1inch}/src/index.ts (100%) create mode 100644 typescript/packages/plugins/1inch/src/parameters.ts rename typescript/packages/plugins/{1inch-balance => 1inch}/src/types.ts (100%) rename typescript/packages/plugins/{1inch-balance => 1inch}/tsconfig.json (100%) rename typescript/packages/plugins/{1inch-balance => 1inch}/tsup.config.ts (100%) diff --git a/goat.code-workspace b/goat.code-workspace index 2cfae05a..fc930985 100644 --- a/goat.code-workspace +++ b/goat.code-workspace @@ -118,6 +118,10 @@ "name": "[Plugin] 🗿 ironclad", "path": "./typescript/packages/plugins/ironclad" }, + { + "name": "[Plugin] 🐎 1inch", + "path": "./typescript/packages/plugins/1inch" + }, { "name": "[Plugin] 🦄 uniswap", "path": "./typescript/packages/plugins/uniswap" diff --git a/typescript/packages/plugins/1inch-balance/src/parameters.ts b/typescript/packages/plugins/1inch-balance/src/parameters.ts deleted file mode 100644 index f2548b56..00000000 --- a/typescript/packages/plugins/1inch-balance/src/parameters.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createToolParameters } from "@goat-sdk/core"; -import { z } from "zod"; - -export class GetAggregatedBalancesAndAllowancesParameters extends createToolParameters( - z.object({ - chain: z.number().describe("The chain ID to query balances on"), - spender: z.string().describe("The spender address to check allowances for"), - wallets: z.array(z.string()).describe("List of wallet addresses to check balances for"), - filterEmpty: z.boolean().optional().describe("Whether to filter out empty balances"), - }), -) {} diff --git a/typescript/packages/plugins/1inch-balance/package.json b/typescript/packages/plugins/1inch/package.json similarity index 79% rename from typescript/packages/plugins/1inch-balance/package.json rename to typescript/packages/plugins/1inch/package.json index cdb06930..ca1b3efe 100644 --- a/typescript/packages/plugins/1inch-balance/package.json +++ b/typescript/packages/plugins/1inch/package.json @@ -1,6 +1,6 @@ { - "name": "@goat-sdk/plugin-1inch-balance", - "version": "0.0.1", + "name": "@goat-sdk/plugin-1inch", + "version": "0.1.0", "files": ["dist/**/*", "README.md", "package.json"], "scripts": { "build": "tsup", @@ -14,10 +14,12 @@ "types": "./dist/index.d.ts", "dependencies": { "@goat-sdk/core": "workspace:*", + "@goat-sdk/wallet-evm": "workspace:*", "zod": "catalog:" }, "peerDependencies": { - "@goat-sdk/core": "workspace:*" + "@goat-sdk/core": "workspace:*", + "@goat-sdk/wallet-evm": "workspace:*" }, "homepage": "https://ohmygoat.dev", "repository": { diff --git a/typescript/packages/plugins/1inch-balance/src/balance.service.ts b/typescript/packages/plugins/1inch/src/balance.service.ts similarity index 52% rename from typescript/packages/plugins/1inch-balance/src/balance.service.ts rename to typescript/packages/plugins/1inch/src/balance.service.ts index 264ad9fb..84d39dd4 100644 --- a/typescript/packages/plugins/1inch-balance/src/balance.service.ts +++ b/typescript/packages/plugins/1inch/src/balance.service.ts @@ -1,5 +1,6 @@ import { Tool } from "@goat-sdk/core"; -import { GetAggregatedBalancesAndAllowancesParameters } from "./parameters"; +import { EVMWalletClient } from "@goat-sdk/wallet-evm"; +import { GetBalancesParameters } from "./parameters"; import { AggregatedBalancesAndAllowancesResponse, BalanceServiceParams } from "./types"; export class BalanceService { @@ -7,24 +8,24 @@ export class BalanceService { private readonly apiKey?: string; constructor(params: BalanceServiceParams = {}) { - this.baseUrl = params.baseUrl ?? "https://api.1inch.dev/balance"; + this.baseUrl = params.baseUrl ?? "https://api.1inch.dev"; this.apiKey = params.apiKey; } @Tool({ - description: - "Get aggregated balances and allowances for a list of wallet addresses, checking their token balances and allowances for a specific spender address.", + name: "1inch.get_balances", + description: "Get the balances of a wallet address on a specific chain", }) async getAggregatedBalancesAndAllowances( - parameters: GetAggregatedBalancesAndAllowancesParameters, + walletClient: EVMWalletClient, + parameters: GetBalancesParameters, ): Promise { - const { chain, spender, wallets, filterEmpty } = parameters; + const { walletAddress } = parameters; + const chainId = walletClient.getChain().id; - const url = new URL(`${this.baseUrl}/v1.2/${chain}/aggregatedBalancesAndAllowances/${spender}`); - url.searchParams.append("wallets", wallets.join(",")); - if (filterEmpty !== undefined) { - url.searchParams.append("filterEmpty", String(filterEmpty)); - } + const url = new URL( + `${this.baseUrl}/balance/v1.2/${chainId}/balances/${walletAddress ?? walletClient.getAddress()}`, + ); const response = await fetch(url.toString(), { headers: { diff --git a/typescript/packages/plugins/1inch-balance/src/index.ts b/typescript/packages/plugins/1inch/src/index.ts similarity index 100% rename from typescript/packages/plugins/1inch-balance/src/index.ts rename to typescript/packages/plugins/1inch/src/index.ts diff --git a/typescript/packages/plugins/1inch/src/parameters.ts b/typescript/packages/plugins/1inch/src/parameters.ts new file mode 100644 index 00000000..5eeddda7 --- /dev/null +++ b/typescript/packages/plugins/1inch/src/parameters.ts @@ -0,0 +1,8 @@ +import { createToolParameters } from "@goat-sdk/core"; +import { z } from "zod"; + +export class GetBalancesParameters extends createToolParameters( + z.object({ + walletAddress: z.string().optional().describe("The wallet address to check balances for"), + }), +) {} diff --git a/typescript/packages/plugins/1inch-balance/src/types.ts b/typescript/packages/plugins/1inch/src/types.ts similarity index 100% rename from typescript/packages/plugins/1inch-balance/src/types.ts rename to typescript/packages/plugins/1inch/src/types.ts diff --git a/typescript/packages/plugins/1inch-balance/tsconfig.json b/typescript/packages/plugins/1inch/tsconfig.json similarity index 100% rename from typescript/packages/plugins/1inch-balance/tsconfig.json rename to typescript/packages/plugins/1inch/tsconfig.json diff --git a/typescript/packages/plugins/1inch-balance/tsup.config.ts b/typescript/packages/plugins/1inch/tsup.config.ts similarity index 100% rename from typescript/packages/plugins/1inch-balance/tsup.config.ts rename to typescript/packages/plugins/1inch/tsup.config.ts diff --git a/typescript/pnpm-lock.yaml b/typescript/pnpm-lock.yaml index 4c518f1c..b3efe3ee 100644 --- a/typescript/pnpm-lock.yaml +++ b/typescript/pnpm-lock.yaml @@ -895,11 +895,14 @@ importers: specifier: 'catalog:' version: 3.23.8 - packages/plugins/1inch-balance: + packages/plugins/1inch: dependencies: '@goat-sdk/core': specifier: workspace:* version: link:../../core + '@goat-sdk/wallet-evm': + specifier: workspace:* + version: link:../../wallets/evm zod: specifier: 'catalog:' version: 3.23.8 From 9be14fc4119cdf71735909b0dde8e89e9739fe2e Mon Sep 17 00:00:00 2001 From: Agustin Armellini Fischer Date: Sat, 4 Jan 2025 17:11:43 +0100 Subject: [PATCH 3/3] Fix dependencies --- typescript/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/typescript/package.json b/typescript/package.json index a330a9e2..dcadac10 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -24,9 +24,6 @@ "cross-env": "7.0.3", "globals": "15.12.0", "rimraf": "6.0.1", - "@goat-sdk/core": "workspace:*", - "node-fetch": "^3.0.0", - "zod": "^3.0.0", "ts-node": "10.9.2", "tsc-alias": "1.8.10", "tsup": "8.3.5",