diff --git a/.github/actions/pnpm-install/action.yml b/.github/actions/pnpm-install/action.yml new file mode 100644 index 000000000..21ca9bed6 --- /dev/null +++ b/.github/actions/pnpm-install/action.yml @@ -0,0 +1,71 @@ +name: "Setup Node.js, PNPM, and install dependencies" + +inputs: + node-version: + description: "Node.js version to use" + required: false + default: 20.12.2 + pnpm-version: + description: "PNPM version to use" + required: false + default: 9.14.2 + skip-install: + description: "Skip 'pnpm install'" + required: false + default: false + install-args: + description: "Additional args supplied to 'pnpm install'" + required: false + working-directory: + description: "Working directory to run the command in" + required: false + default: ./typescript + +runs: + using: "composite" + + steps: + - name: Log inputs + shell: bash + run: | + echo "Node.js version: ${{ inputs.node-version }}" + echo "PNPM version: ${{ inputs.pnpm-version }}" + echo "Skip install: ${{ inputs.skip-install }}" + echo "Install args: ${{ inputs.install-args }}" + echo "Working directory: ${{ inputs.working-directory }}" + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.pnpm-version }} + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + + - id: pnpm-config + if: inputs.skip-install == 'false' + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - id: cache-rotation + shell: bash + if: inputs.skip-install == 'false' + run: | + echo "YEAR_MONTH=$(/bin/date -u "+%Y%m")" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + if: inputs.skip-install == 'false' + with: + path: ${{ steps.pnpm-config.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-cache-${{ steps.cache-rotation.outputs.YEAR_MONTH }}-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store-cache-${{ steps.cache-rotation.outputs.YEAR_MONTH }}- + + - name: Install dependencies + shell: bash + if: inputs.skip-install == 'false' + working-directory: ${{ inputs.working-directory }} + run: pnpm install --frozen-lockfile --prefer-offline ${{ inputs.install-args }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..f550e3625 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,23 @@ +name: CI + +on: + push: + +jobs: + build-and-test: + name: build & test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js, PNPM, and install dependencies + uses: ./.github/actions/pnpm-install + + - name: Build all + working-directory: ./typescript + run: pnpm build + + - name: Test all + working-directory: ./typescript + run: pnpm test \ No newline at end of file diff --git a/goat.code-workspace b/goat.code-workspace index 68545e2c6..40cae33f4 100644 --- a/goat.code-workspace +++ b/goat.code-workspace @@ -4,6 +4,10 @@ "name": "🐐 GOAT", "path": "." }, + { + "name": "📘 Typescript", + "path": "./typescript" + }, { "name": "🌋 Core", "path": "./typescript/packages/core" diff --git a/typescript/biome.json b/typescript/biome.json index ca11f9570..94fe88458 100644 --- a/typescript/biome.json +++ b/typescript/biome.json @@ -1,30 +1,32 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "vcs": { - "enabled": false, - "clientKind": "git", - "useIgnoreFile": false - }, - "files": { - "ignoreUnknown": false, - "ignore": ["dist/**/*"] - }, - "formatter": { - "enabled": true, - "indentStyle": "tab" - }, - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true - } - }, - "javascript": { - "formatter": { - "quoteStyle": "double" - } - } + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": false + }, + "files": { + "ignoreUnknown": false, + "ignore": ["dist/**/*"] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 120 + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + } } diff --git a/typescript/examples/eleven-labs/conversational-agent/next.config.ts b/typescript/examples/eleven-labs/conversational-agent/next.config.ts index e9ffa3083..c32f48d1b 100644 --- a/typescript/examples/eleven-labs/conversational-agent/next.config.ts +++ b/typescript/examples/eleven-labs/conversational-agent/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + /* config options here */ }; export default nextConfig; diff --git a/typescript/examples/eleven-labs/conversational-agent/package.json b/typescript/examples/eleven-labs/conversational-agent/package.json index d1dab1fd1..173fa3898 100644 --- a/typescript/examples/eleven-labs/conversational-agent/package.json +++ b/typescript/examples/eleven-labs/conversational-agent/package.json @@ -1,32 +1,30 @@ { - "name": "conversational-agent", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@11labs/react": "^0.0.4", - "@goat-sdk/adapter-eleven-labs": "0.1.2", - "@goat-sdk/core": "0.3.10", - "@goat-sdk/wallet-viem": "0.1.3", - "@tanstack/react-query": "^5.62.2", - "connectkit": "^1.8.2", - "next": "15.0.3", - "react": "19.0.0-rc-66855b96-20241106", - "react-dom": "19.0.0-rc-66855b96-20241106", - "viem": "^2.21.49", - "wagmi": "^2.13.3" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "postcss": "^8", - "tailwindcss": "^3.4.1", - "typescript": "^5" - } + "name": "conversational-agent", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@11labs/react": "^0.0.4", + "@goat-sdk/adapter-eleven-labs": "0.1.2", + "@goat-sdk/core": "0.3.10", + "@goat-sdk/wallet-viem": "0.1.3", + "@tanstack/react-query": "^5.62.2", + "connectkit": "^1.8.2", + "next": "15.0.3", + "react": "19.0.0-rc-66855b96-20241106", + "react-dom": "19.0.0-rc-66855b96-20241106", + "viem": "^2.21.49", + "wagmi": "^2.13.3" + }, + "devDependencies": { + "@types/react": "^18", + "@types/react-dom": "^18", + "postcss": "^8", + "tailwindcss": "^3.4.1" + } } diff --git a/typescript/examples/eleven-labs/conversational-agent/postcss.config.mjs b/typescript/examples/eleven-labs/conversational-agent/postcss.config.mjs index 1a69fd2a4..6f943477c 100644 --- a/typescript/examples/eleven-labs/conversational-agent/postcss.config.mjs +++ b/typescript/examples/eleven-labs/conversational-agent/postcss.config.mjs @@ -1,8 +1,8 @@ /** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: { + tailwindcss: {}, + }, }; export default config; diff --git a/typescript/examples/eleven-labs/conversational-agent/src/app/components/conversation.tsx b/typescript/examples/eleven-labs/conversational-agent/src/app/components/conversation.tsx index 9d4c6c5e9..a45ddf716 100644 --- a/typescript/examples/eleven-labs/conversational-agent/src/app/components/conversation.tsx +++ b/typescript/examples/eleven-labs/conversational-agent/src/app/components/conversation.tsx @@ -1,12 +1,12 @@ "use client"; import { useConversation } from "@11labs/react"; -import { useCallback } from "react"; import { getOnChainTools } from "@goat-sdk/adapter-eleven-labs"; +import { useCallback } from "react"; import { viem } from "@goat-sdk/wallet-viem"; -import { useAccount, useWalletClient } from "wagmi"; import { ConnectKitButton } from "connectkit"; +import { useAccount, useWalletClient } from "wagmi"; import { sendETH } from "../../../../../../packages/core/dist/plugins/send-eth"; export function Conversation() { @@ -57,16 +57,12 @@ export function Conversation() {

1. Connect Wallet to start

-

- 2. Start Conversation with Agent -

+

2. Start Conversation with Agent

diff --git a/typescript/examples/eleven-labs/conversational-agent/src/app/globals.css b/typescript/examples/eleven-labs/conversational-agent/src/app/globals.css index 6b717ad34..9f1c09359 100644 --- a/typescript/examples/eleven-labs/conversational-agent/src/app/globals.css +++ b/typescript/examples/eleven-labs/conversational-agent/src/app/globals.css @@ -3,19 +3,19 @@ @tailwind utilities; :root { - --background: #ffffff; - --foreground: #171717; + --background: #ffffff; + --foreground: #171717; } @media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } + :root { + --background: #0a0a0a; + --foreground: #ededed; + } } body { - color: var(--foreground); - background: var(--background); - font-family: Arial, Helvetica, sans-serif; + color: var(--foreground); + background: var(--background); + font-family: Arial, Helvetica, sans-serif; } diff --git a/typescript/examples/eleven-labs/conversational-agent/src/app/layout.tsx b/typescript/examples/eleven-labs/conversational-agent/src/app/layout.tsx index 720357b80..75d8e5cdc 100644 --- a/typescript/examples/eleven-labs/conversational-agent/src/app/layout.tsx +++ b/typescript/examples/eleven-labs/conversational-agent/src/app/layout.tsx @@ -26,9 +26,7 @@ export default function RootLayout({ }>) { return ( - + {children} diff --git a/typescript/examples/eleven-labs/conversational-agent/src/app/page.tsx b/typescript/examples/eleven-labs/conversational-agent/src/app/page.tsx index fe292dcfa..0e43206dc 100644 --- a/typescript/examples/eleven-labs/conversational-agent/src/app/page.tsx +++ b/typescript/examples/eleven-labs/conversational-agent/src/app/page.tsx @@ -4,9 +4,7 @@ export default function Home() { return (
-

- GOAT 🐐 Conversational AI -

+

GOAT 🐐 Conversational AI

diff --git a/typescript/examples/eleven-labs/conversational-agent/src/app/providers.tsx b/typescript/examples/eleven-labs/conversational-agent/src/app/providers.tsx index 9504f8a78..339bfe448 100644 --- a/typescript/examples/eleven-labs/conversational-agent/src/app/providers.tsx +++ b/typescript/examples/eleven-labs/conversational-agent/src/app/providers.tsx @@ -1,9 +1,9 @@ "use client"; -import { WagmiProvider, createConfig, http } from "wagmi"; -import { sepolia } from "wagmi/chains"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConnectKitProvider, getDefaultConfig } from "connectkit"; +import { http, WagmiProvider, createConfig } from "wagmi"; +import { sepolia } from "wagmi/chains"; const config = createConfig( getDefaultConfig({ @@ -15,12 +15,11 @@ const config = createConfig( }, // Required API Keys - walletConnectProjectId: - process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID ?? "", + walletConnectProjectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID ?? "", // Required App Info appName: "GOAT Conversational AI", - }) + }), ); const queryClient = new QueryClient(); diff --git a/typescript/examples/eleven-labs/conversational-agent/tailwind.config.ts b/typescript/examples/eleven-labs/conversational-agent/tailwind.config.ts index 109807be0..908649557 100644 --- a/typescript/examples/eleven-labs/conversational-agent/tailwind.config.ts +++ b/typescript/examples/eleven-labs/conversational-agent/tailwind.config.ts @@ -1,18 +1,18 @@ import type { Config } from "tailwindcss"; export default { - content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - colors: { - background: "var(--background)", - foreground: "var(--foreground)", - }, + content: [ + "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", + "./src/components/**/*.{js,ts,jsx,tsx,mdx}", + "./src/app/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: { + colors: { + background: "var(--background)", + foreground: "var(--foreground)", + }, + }, }, - }, - plugins: [], + plugins: [], } satisfies Config; diff --git a/typescript/examples/eleven-labs/conversational-agent/tsconfig.json b/typescript/examples/eleven-labs/conversational-agent/tsconfig.json index c1334095f..06ee0dbcb 100644 --- a/typescript/examples/eleven-labs/conversational-agent/tsconfig.json +++ b/typescript/examples/eleven-labs/conversational-agent/tsconfig.json @@ -1,27 +1,27 @@ { - "compilerOptions": { - "target": "ES2017", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] } diff --git a/typescript/examples/langchain/viem/index.ts b/typescript/examples/langchain/viem/index.ts index 80d465a04..6c556a496 100644 --- a/typescript/examples/langchain/viem/index.ts +++ b/typescript/examples/langchain/viem/index.ts @@ -1,7 +1,7 @@ -import { ChatOpenAI } from "@langchain/openai"; import type { ChatPromptTemplate } from "@langchain/core/prompts"; -import { pull } from "langchain/hub"; +import { ChatOpenAI } from "@langchain/openai"; import { AgentExecutor, createStructuredChatAgent } from "langchain/agents"; +import { pull } from "langchain/hub"; import { http } from "viem"; import { createWalletClient } from "viem"; @@ -11,14 +11,12 @@ import { sepolia } from "viem/chains"; import { getOnChainTools } from "@goat-sdk/adapter-langchain"; import { PEPE, USDC, erc20 } from "@goat-sdk/plugin-erc20"; -import { viem } from "@goat-sdk/wallet-viem"; import { sendETH } from "@goat-sdk/core"; +import { viem } from "@goat-sdk/wallet-viem"; require("dotenv").config(); -const account = privateKeyToAccount( - process.env.WALLET_PRIVATE_KEY as `0x${string}` -); +const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); const walletClient = createWalletClient({ account: account, @@ -31,9 +29,7 @@ const llm = new ChatOpenAI({ }); (async (): Promise => { - const prompt = await pull( - "hwchase17/structured-chat-agent" - ); + const prompt = await pull("hwchase17/structured-chat-agent"); const tools = await getOnChainTools({ wallet: viem(walletClient), diff --git a/typescript/examples/langchain/viem/package.json b/typescript/examples/langchain/viem/package.json index afbc08dba..694859dfb 100644 --- a/typescript/examples/langchain/viem/package.json +++ b/typescript/examples/langchain/viem/package.json @@ -1,25 +1,22 @@ { - "name": "goat-examples-langchain-viem", - "version": "0.1.0", - "description": "", - "private": true, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "MIT", - "dependencies": { - "@goat-sdk/adapter-langchain": "0.1.4", - "@goat-sdk/core": "0.3.8", - "@goat-sdk/plugin-erc20": "0.1.4", - "@goat-sdk/wallet-viem": "0.1.3", - "@langchain/core": "^0.3.6", - "@langchain/openai": "^0.3.5", - "dotenv": "^16.4.5", - "viem": "2.21.49", - "langchain": "^0.3.2" - }, - "devDependencies": { - "@types/node": "^22.7.4" - } + "name": "goat-examples-langchain-viem", + "version": "0.1.0", + "description": "", + "private": true, + "scripts": { + "test": "vitest run --passWithNoTests" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@goat-sdk/adapter-langchain": "0.1.4", + "@goat-sdk/core": "0.3.8", + "@goat-sdk/plugin-erc20": "0.1.4", + "@goat-sdk/wallet-viem": "0.1.3", + "@langchain/core": "^0.3.6", + "@langchain/openai": "^0.3.5", + "dotenv": "^16.4.5", + "viem": "2.21.49", + "langchain": "^0.3.2" + } } diff --git a/typescript/examples/langchain/viem/tsconfig.json b/typescript/examples/langchain/viem/tsconfig.json index 6db2f3a9d..a7fc4a937 100644 --- a/typescript/examples/langchain/viem/tsconfig.json +++ b/typescript/examples/langchain/viem/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["index.ts"], - "exclude": ["node_modules", "dist"] + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["index.ts"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/examples/vercel-ai/crossmint-smart-wallets/create-smart-wallet.ts b/typescript/examples/vercel-ai/crossmint-smart-wallets/create-smart-wallet.ts index ea00de3db..5bbae9c3d 100644 --- a/typescript/examples/vercel-ai/crossmint-smart-wallets/create-smart-wallet.ts +++ b/typescript/examples/vercel-ai/crossmint-smart-wallets/create-smart-wallet.ts @@ -7,41 +7,38 @@ const walletAddress = process.env.SIGNER_WALLET_ADDRESS; const walletSignerSecretKey = process.env.SIGNER_WALLET_SECRET_KEY; if (!apiKey || !walletAddress || !walletSignerSecretKey) { - throw new Error("Missing environment variables"); + throw new Error("Missing environment variables"); } (async () => { - const response = await createWallet(walletAddress as `0x${string}`, apiKey); + const response = await createWallet(walletAddress as `0x${string}`, apiKey); - if (response.error) { - console.error(response.error); - return; - } + if (response.error) { + console.error(response.error); + return; + } - console.log(`Created wallet: ${response.address}`); - console.log(`Details: ${JSON.stringify(response, null, 2)}`); + console.log(`Created wallet: ${response.address}`); + console.log(`Details: ${JSON.stringify(response, null, 2)}`); })(); async function createWallet(signerPublicKey: `0x${string}`, apiKey: string) { - const response = await fetch( - "https://staging.crossmint.com/api/v1-alpha2/wallets", - { - method: "POST", - headers: { - "X-API-KEY": apiKey, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - type: "evm-smart-wallet", - config: { - adminSigner: { - type: "evm-keypair", - address: signerPublicKey, - }, - }, - }), - }, - ); - - return await response.json(); + const response = await fetch("https://staging.crossmint.com/api/v1-alpha2/wallets", { + method: "POST", + headers: { + "X-API-KEY": apiKey, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + type: "evm-smart-wallet", + config: { + adminSigner: { + type: "evm-keypair", + address: signerPublicKey, + }, + }, + }), + }); + + return await response.json(); } diff --git a/typescript/examples/vercel-ai/crossmint-smart-wallets/index.ts b/typescript/examples/vercel-ai/crossmint-smart-wallets/index.ts index dff3541f3..6233fbd16 100644 --- a/typescript/examples/vercel-ai/crossmint-smart-wallets/index.ts +++ b/typescript/examples/vercel-ai/crossmint-smart-wallets/index.ts @@ -2,9 +2,9 @@ import { openai } from "@ai-sdk/openai"; import { generateText } from "ai"; import { getOnChainTools } from "@goat-sdk/adapter-vercel-ai"; +import { sendETH } from "@goat-sdk/core"; import { crossmint } from "@goat-sdk/crossmint"; import { USDC, erc20 } from "@goat-sdk/plugin-erc20"; -import { sendETH } from "@goat-sdk/core"; require("dotenv").config(); @@ -13,12 +13,7 @@ const walletSignerSecretKey = process.env.SIGNER_WALLET_SECRET_KEY; const alchemyApiKey = process.env.ALCHEMY_API_KEY_BASE_SEPOLIA; const smartWalletAddress = process.env.SMART_WALLET_ADDRESS; -if ( - !apiKey || - !walletSignerSecretKey || - !alchemyApiKey || - !smartWalletAddress -) { +if (!apiKey || !walletSignerSecretKey || !alchemyApiKey || !smartWalletAddress) { throw new Error("Missing environment variables"); } diff --git a/typescript/examples/vercel-ai/crossmint-smart-wallets/package.json b/typescript/examples/vercel-ai/crossmint-smart-wallets/package.json index 3afb9a86a..4da34c4c6 100644 --- a/typescript/examples/vercel-ai/crossmint-smart-wallets/package.json +++ b/typescript/examples/vercel-ai/crossmint-smart-wallets/package.json @@ -1,25 +1,22 @@ { - "name": "goat-examples-vercel-ai-crossmint-smart-wallets", - "version": "0.1.0", - "private": true, - "description": "", - "scripts": { - "create-wallet": "ts-node create-smart-wallet.ts", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "MIT", - "dependencies": { - "@ai-sdk/openai": "^1.0.4", - "@goat-sdk/adapter-vercel-ai": "0.1.4", - "@goat-sdk/core": "0.3.5", - "@goat-sdk/plugin-erc20": "0.1.4", - "@goat-sdk/crossmint": "0.1.4", - "ai": "^4.0.3", - "dotenv": "^16.4.5", - "viem": "2.21.49" - }, - "devDependencies": { - "@types/node": "^22.9.1" - } + "name": "goat-examples-vercel-ai-crossmint-smart-wallets", + "version": "0.1.0", + "private": true, + "description": "", + "scripts": { + "create-wallet": "ts-node create-smart-wallet.ts", + "test": "vitest run --passWithNoTests" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@ai-sdk/openai": "^1.0.4", + "@goat-sdk/adapter-vercel-ai": "0.1.4", + "@goat-sdk/core": "0.3.5", + "@goat-sdk/plugin-erc20": "0.1.4", + "@goat-sdk/crossmint": "0.1.4", + "ai": "^4.0.3", + "dotenv": "^16.4.5", + "viem": "2.21.49" + } } diff --git a/typescript/examples/vercel-ai/crossmint-smart-wallets/tsconfig.json b/typescript/examples/vercel-ai/crossmint-smart-wallets/tsconfig.json index 20268019f..6a792d30e 100644 --- a/typescript/examples/vercel-ai/crossmint-smart-wallets/tsconfig.json +++ b/typescript/examples/vercel-ai/crossmint-smart-wallets/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["index.ts", "create-smart-wallet.ts"], - "exclude": ["node_modules", "dist"] + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["index.ts", "create-smart-wallet.ts"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/create-custodial-wallet.ts b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/create-custodial-wallet.ts index b12e3dfeb..a66e899ad 100644 --- a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/create-custodial-wallet.ts +++ b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/create-custodial-wallet.ts @@ -6,36 +6,33 @@ const apiKey = process.env.CROSSMINT_STAGING_API_KEY; const email = process.env.EMAIL; if (!apiKey || !email) { - throw new Error("Missing environment variables"); + throw new Error("Missing environment variables"); } (async () => { - const response = await createWallet(email, apiKey); + const response = await createWallet(email, apiKey); - if (response.error) { - console.error(response.error); - return; - } + if (response.error) { + console.error(response.error); + return; + } - console.log(`Created wallet: ${response.address}`); - console.log(`Details: ${JSON.stringify(response, null, 2)}`); + console.log(`Created wallet: ${response.address}`); + console.log(`Details: ${JSON.stringify(response, null, 2)}`); })(); async function createWallet(email: string, apiKey: string) { - const response = await fetch( - "https://staging.crossmint.com/api/v1-alpha2/wallets", - { - method: "POST", - headers: { - "X-API-KEY": apiKey, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - type: "solana-custodial-wallet", - linkedUser: `email:${email}`, - }), - }, - ); - - return await response.json(); + const response = await fetch("https://staging.crossmint.com/api/v1-alpha2/wallets", { + method: "POST", + headers: { + "X-API-KEY": apiKey, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + type: "solana-custodial-wallet", + linkedUser: `email:${email}`, + }), + }); + + return await response.json(); } diff --git a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/index.ts b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/index.ts index 7b69ae3c6..7bbc35b4b 100644 --- a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/index.ts +++ b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/index.ts @@ -11,27 +11,27 @@ const apiKey = process.env.CROSSMINT_STAGING_API_KEY; const email = process.env.EMAIL; if (!apiKey || !email) { - throw new Error("Missing environment variables"); + throw new Error("Missing environment variables"); } const { custodial } = crossmint(apiKey); (async () => { - const tools = await getOnChainTools({ - wallet: await custodial({ - chain: "solana", - email: email, - env: "staging", - connection: new Connection("https://api.devnet.solana.com", "confirmed"), - }), - }); - - const result = await generateText({ - model: openai("gpt-4o-mini"), - tools: tools, - maxSteps: 5, - prompt: "Get my balance in SOL", - }); - - console.log(result.text); + const tools = await getOnChainTools({ + wallet: await custodial({ + chain: "solana", + email: email, + env: "staging", + connection: new Connection("https://api.devnet.solana.com", "confirmed"), + }), + }); + + const result = await generateText({ + model: openai("gpt-4o-mini"), + tools: tools, + maxSteps: 5, + prompt: "Get my balance in SOL", + }); + + console.log(result.text); })(); diff --git a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/package.json b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/package.json index 9b0dbff83..91df26498 100644 --- a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/package.json +++ b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/package.json @@ -1,26 +1,23 @@ { - "name": "goat-examples-vercel-ai-crossmint-solana-custodial-wallets", - "version": "0.1.0", - "description": "", - "private": true, - "scripts": { - "create-wallet": "ts-node create-custodial-wallet.ts", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "MIT", - "dependencies": { - "@ai-sdk/openai": "^1.0.4", - "@goat-sdk/adapter-vercel-ai": "0.1.4", - "@goat-sdk/core": "0.3.8", - "@goat-sdk/plugin-erc20": "0.1.4", - "@goat-sdk/crossmint": "0.1.4", - "@solana/web3.js": "1.95.8", - "ai": "^4.0.3", - "dotenv": "^16.4.5", - "viem": "2.21.49" - }, - "devDependencies": { - "@types/node": "^22.9.1" - } + "name": "goat-examples-vercel-ai-crossmint-solana-custodial-wallets", + "version": "0.1.0", + "description": "", + "private": true, + "scripts": { + "create-wallet": "ts-node create-custodial-wallet.ts", + "test": "vitest run --passWithNoTests" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@ai-sdk/openai": "^1.0.4", + "@goat-sdk/adapter-vercel-ai": "0.1.4", + "@goat-sdk/core": "0.3.8", + "@goat-sdk/plugin-erc20": "0.1.4", + "@goat-sdk/crossmint": "0.1.4", + "@solana/web3.js": "1.95.8", + "ai": "^4.0.3", + "dotenv": "^16.4.5", + "viem": "2.21.49" + } } diff --git a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/tsconfig.json b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/tsconfig.json index e2a4afc32..ebc635ada 100644 --- a/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/tsconfig.json +++ b/typescript/examples/vercel-ai/crossmint-solana-custodial-wallets/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["index.ts", "create-custodial-wallet.ts"], - "exclude": ["node_modules", "dist"] + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["index.ts", "create-custodial-wallet.ts"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/examples/vercel-ai/polymarket/create-or-derive-api-key.ts b/typescript/examples/vercel-ai/polymarket/create-or-derive-api-key.ts index 35ca6731a..79af85336 100644 --- a/typescript/examples/vercel-ai/polymarket/create-or-derive-api-key.ts +++ b/typescript/examples/vercel-ai/polymarket/create-or-derive-api-key.ts @@ -2,17 +2,15 @@ import dotenv from "dotenv"; dotenv.config(); -import { privateKeyToAccount } from "viem/accounts"; import { createWalletClient } from "viem"; import { http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; import { polygon } from "viem/chains"; import { createOrDeriveAPIKey } from "@goat-sdk/plugin-polymarket"; import { viem } from "@goat-sdk/wallet-viem"; -const account = privateKeyToAccount( - process.env.WALLET_PRIVATE_KEY as `0x${string}` -); +const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); const walletClient = createWalletClient({ account: account, diff --git a/typescript/examples/vercel-ai/polymarket/index.ts b/typescript/examples/vercel-ai/polymarket/index.ts index 5ce765e4c..9b59dac26 100644 --- a/typescript/examples/vercel-ai/polymarket/index.ts +++ b/typescript/examples/vercel-ai/polymarket/index.ts @@ -12,9 +12,7 @@ import { viem } from "@goat-sdk/wallet-viem"; require("dotenv").config(); -const account = privateKeyToAccount( - process.env.WALLET_PRIVATE_KEY as `0x${string}`, -); +const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); const walletClient = createWalletClient({ account: account, @@ -23,25 +21,25 @@ const walletClient = createWalletClient({ }); (async () => { - const tools = await getOnChainTools({ - wallet: viem(walletClient), - plugins: [ - polymarket({ - credentials: { - key: process.env.POLYMARKET_API_KEY as string, - secret: process.env.POLYMARKET_SECRET as string, - passphrase: process.env.POLYMARKET_PASSPHRASE as string, - }, - }), - ], - }); - - const result = await generateText({ + const tools = await getOnChainTools({ + wallet: viem(walletClient), + plugins: [ + polymarket({ + credentials: { + key: process.env.POLYMARKET_API_KEY as string, + secret: process.env.POLYMARKET_SECRET as string, + passphrase: process.env.POLYMARKET_PASSPHRASE as string, + }, + }), + ], + }); + + const result = await generateText({ model: openai("gpt-4o-mini"), tools: tools, maxSteps: 5, prompt: "List all my active orders on Polymarket", }); - console.log(result.text); + console.log(result.text); })(); diff --git a/typescript/examples/vercel-ai/polymarket/package.json b/typescript/examples/vercel-ai/polymarket/package.json index d852ac38e..91bada622 100644 --- a/typescript/examples/vercel-ai/polymarket/package.json +++ b/typescript/examples/vercel-ai/polymarket/package.json @@ -1,27 +1,24 @@ { - "name": "goat-examples-vercel-ai-polymarket", - "version": "0.1.0", - "description": "", - "private": true, - "scripts": { - "polymarket:api-key": "ts-node create-or-derive-api-key.ts", - "polymarket:setup-allowance": "ts-node setup-allowance.ts", - "polymarket:test-create-order": "ts-node test-create-order.ts", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "MIT", - "dependencies": { - "@ai-sdk/openai": "^1.0.4", - "@goat-sdk/adapter-vercel-ai": "0.1.4", - "@goat-sdk/core": "0.3.8", - "@goat-sdk/plugin-polymarket": "workspace:*", - "@goat-sdk/wallet-viem": "0.1.3", - "ai": "^4.0.3", - "dotenv": "^16.4.5", - "viem": "2.21.49" - }, - "devDependencies": { - "@types/node": "^22.7.4" - } + "name": "goat-examples-vercel-ai-polymarket", + "version": "0.1.0", + "description": "", + "private": true, + "scripts": { + "polymarket:api-key": "ts-node create-or-derive-api-key.ts", + "polymarket:setup-allowance": "ts-node setup-allowance.ts", + "polymarket:test-create-order": "ts-node test-create-order.ts", + "test": "vitest run --passWithNoTests" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@ai-sdk/openai": "^1.0.4", + "@goat-sdk/adapter-vercel-ai": "0.1.4", + "@goat-sdk/core": "0.3.8", + "@goat-sdk/plugin-polymarket": "workspace:*", + "@goat-sdk/wallet-viem": "0.1.3", + "ai": "^4.0.3", + "dotenv": "^16.4.5", + "viem": "2.21.49" + } } diff --git a/typescript/examples/vercel-ai/polymarket/setup-allowance.ts b/typescript/examples/vercel-ai/polymarket/setup-allowance.ts index 488487ef0..0f7ea0be6 100644 --- a/typescript/examples/vercel-ai/polymarket/setup-allowance.ts +++ b/typescript/examples/vercel-ai/polymarket/setup-allowance.ts @@ -2,12 +2,12 @@ import dotenv from "dotenv"; dotenv.config(); -import { privateKeyToAccount } from "viem/accounts"; +import { viem } from "@goat-sdk/wallet-viem"; import { createWalletClient } from "viem"; import { http } from "viem"; -import { polygon } from "viem/chains"; -import { viem } from "@goat-sdk/wallet-viem"; import { parseAbi } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { polygon } from "viem/chains"; export const ERC20_ABI = parseAbi([ "function allowance(address owner, address spender) external view returns (uint256)", @@ -19,8 +19,7 @@ const ERC1155_ABI = parseAbi([ "function setApprovalForAll(address operator, bool approved) external", ]); -const MAX_ALLOWANCE = - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; +const MAX_ALLOWANCE = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // Define the contract configurations type ContractConfig = { @@ -41,9 +40,7 @@ const POLYGON_CONTRACTS: ContractConfig = { }; // Initialize the wallet client -const account = privateKeyToAccount( - process.env.WALLET_PRIVATE_KEY as `0x${string}` -); +const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); const chain = polygon; @@ -79,16 +76,13 @@ const wallet = viem(walletClient); if (value === 0n) { console.log(`Approving USDC for ${address}`); // Approve USDC - const { hash: usdcApproveHash } = - await wallet.sendTransaction({ - to: contractConfig.usdc, - abi: ERC20_ABI, - functionName: "approve", - args: [address, MAX_ALLOWANCE], - }); - console.log( - `Approved USDC for ${address}: ${usdcApproveHash}` - ); + const { hash: usdcApproveHash } = await wallet.sendTransaction({ + to: contractConfig.usdc, + abi: ERC20_ABI, + functionName: "approve", + args: [address, MAX_ALLOWANCE], + }); + console.log(`Approved USDC for ${address}: ${usdcApproveHash}`); } else { console.log(`USDC already approved for ${address}`); } @@ -108,17 +102,14 @@ const wallet = viem(walletClient); if (!isApprovedForAll) { console.log(`Approving CTF for ${address}`); // Approve CTF - const { hash: ctfApproveHash } = - await wallet.sendTransaction({ - to: contractConfig.ctf, - abi: ERC1155_ABI, - functionName: "setApprovalForAll", - args: [address, true], - }); - - console.log( - `Approved CTF for ${address}: ${ctfApproveHash}` - ); + const { hash: ctfApproveHash } = await wallet.sendTransaction({ + to: contractConfig.ctf, + abi: ERC1155_ABI, + functionName: "setApprovalForAll", + args: [address, true], + }); + + console.log(`Approved CTF for ${address}: ${ctfApproveHash}`); } else { console.log(`CTF already approved for ${address}`); } diff --git a/typescript/examples/vercel-ai/polymarket/test-create-order.ts b/typescript/examples/vercel-ai/polymarket/test-create-order.ts index 2abdea87b..e3d8d02d0 100644 --- a/typescript/examples/vercel-ai/polymarket/test-create-order.ts +++ b/typescript/examples/vercel-ai/polymarket/test-create-order.ts @@ -2,17 +2,15 @@ import dotenv from "dotenv"; dotenv.config(); -import { privateKeyToAccount } from "viem/accounts"; import { createWalletClient } from "viem"; import { http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; import { polygon, polygonAmoy } from "viem/chains"; import { createOrder } from "@goat-sdk/plugin-polymarket"; import { viem } from "@goat-sdk/wallet-viem"; -const account = privateKeyToAccount( - process.env.WALLET_PRIVATE_KEY as `0x${string}` -); +const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); const walletClient = createWalletClient({ account: account, @@ -33,13 +31,12 @@ const wallet = viem(walletClient); }, { type: "GTC", - tokenId: - "96937810338362097614741657517268729837129429712920385069363769157847960753005", + tokenId: "96937810338362097614741657517268729837129429712920385069363769157847960753005", price: "0.06", size: 10, expiration: 0, side: "BUY", - } + }, ); console.log(order); diff --git a/typescript/examples/vercel-ai/polymarket/tsconfig.json b/typescript/examples/vercel-ai/polymarket/tsconfig.json index 6db2f3a9d..a7fc4a937 100644 --- a/typescript/examples/vercel-ai/polymarket/tsconfig.json +++ b/typescript/examples/vercel-ai/polymarket/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["index.ts"], - "exclude": ["node_modules", "dist"] + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["index.ts"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/examples/vercel-ai/solana/index.ts b/typescript/examples/vercel-ai/solana/index.ts index c1044197b..8e1922b05 100644 --- a/typescript/examples/vercel-ai/solana/index.ts +++ b/typescript/examples/vercel-ai/solana/index.ts @@ -4,16 +4,13 @@ import { generateText } from "ai"; import { getOnChainTools } from "@goat-sdk/adapter-vercel-ai"; import { solana } from "@goat-sdk/wallet-solana"; +import { sendSOL } from "@goat-sdk/core"; import { Connection, Keypair } from "@solana/web3.js"; import * as bip39 from "bip39"; -import { sendSOL } from "@goat-sdk/core"; require("dotenv").config(); -const connection = new Connection( - "https://api.mainnet-beta.solana.com", - "confirmed" -); +const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed"); const mnemonic = process.env.WALLET_MNEMONIC; diff --git a/typescript/examples/vercel-ai/solana/package.json b/typescript/examples/vercel-ai/solana/package.json index 4a3db5aaf..7833eb71a 100644 --- a/typescript/examples/vercel-ai/solana/package.json +++ b/typescript/examples/vercel-ai/solana/package.json @@ -1,25 +1,22 @@ { - "name": "goat-examples-vercel-ai-solana", - "version": "0.1.0", - "description": "", - "private": true, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "MIT", - "dependencies": { - "@ai-sdk/openai": "^1.0.4", - "@goat-sdk/adapter-vercel-ai": "0.1.4", - "@goat-sdk/core": "0.3.8", - "@goat-sdk/plugin-erc20": "0.1.4", - "@goat-sdk/wallet-solana": "0.1.3", - "@solana/web3.js": "1.95.8", - "ai": "^4.0.3", - "bip39": "^3.1.0", - "dotenv": "^16.4.5" - }, - "devDependencies": { - "@types/node": "^22.7.4" - } + "name": "goat-examples-vercel-ai-solana", + "version": "0.1.0", + "description": "", + "private": true, + "scripts": { + "test": "vitest run --passWithNoTests" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@ai-sdk/openai": "^1.0.4", + "@goat-sdk/adapter-vercel-ai": "0.1.4", + "@goat-sdk/core": "0.3.8", + "@goat-sdk/plugin-erc20": "0.1.4", + "@goat-sdk/wallet-solana": "0.1.3", + "@solana/web3.js": "1.95.8", + "ai": "^4.0.3", + "bip39": "^3.1.0", + "dotenv": "^16.4.5" + } } diff --git a/typescript/examples/vercel-ai/solana/tsconfig.json b/typescript/examples/vercel-ai/solana/tsconfig.json index 6db2f3a9d..a7fc4a937 100644 --- a/typescript/examples/vercel-ai/solana/tsconfig.json +++ b/typescript/examples/vercel-ai/solana/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["index.ts"], - "exclude": ["node_modules", "dist"] + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["index.ts"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/examples/vercel-ai/viem/index.ts b/typescript/examples/vercel-ai/viem/index.ts index 90e7e489b..7a6497c4a 100644 --- a/typescript/examples/vercel-ai/viem/index.ts +++ b/typescript/examples/vercel-ai/viem/index.ts @@ -9,19 +9,17 @@ import { sepolia } from "viem/chains"; import { getOnChainTools } from "@goat-sdk/adapter-vercel-ai"; import { PEPE, USDC, erc20 } from "@goat-sdk/plugin-erc20"; -import { viem } from "@goat-sdk/wallet-viem"; import { sendETH } from "@goat-sdk/core"; +import { viem } from "@goat-sdk/wallet-viem"; require("dotenv").config(); -const account = privateKeyToAccount( - process.env.WALLET_PRIVATE_KEY as `0x${string}`, -); +const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); const walletClient = createWalletClient({ - account: account, - transport: http(process.env.ALCHEMY_API_KEY), - chain: sepolia, + account: account, + transport: http(process.env.ALCHEMY_API_KEY), + chain: sepolia, }); (async () => { @@ -40,4 +38,4 @@ const walletClient = createWalletClient({ }); console.log(result.text); -})(); \ No newline at end of file +})(); diff --git a/typescript/examples/vercel-ai/viem/package.json b/typescript/examples/vercel-ai/viem/package.json index 876f8ddfc..8ab87ec4f 100644 --- a/typescript/examples/vercel-ai/viem/package.json +++ b/typescript/examples/vercel-ai/viem/package.json @@ -1,24 +1,21 @@ { - "name": "goat-examples-vercel-ai-viem", - "version": "0.1.0", - "description": "", - "private": true, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "MIT", - "dependencies": { - "@ai-sdk/openai": "^1.0.4", - "@goat-sdk/adapter-vercel-ai": "0.1.4", - "@goat-sdk/core": "0.3.8", - "@goat-sdk/plugin-erc20": "0.1.4", - "@goat-sdk/wallet-viem": "0.1.3", - "ai": "^4.0.3", - "dotenv": "^16.4.5", - "viem": "2.21.49" - }, - "devDependencies": { - "@types/node": "^22.7.4" - } + "name": "goat-examples-vercel-ai-viem", + "version": "0.1.0", + "description": "", + "private": true, + "scripts": { + "test": "vitest run --passWithNoTests" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@ai-sdk/openai": "^1.0.4", + "@goat-sdk/adapter-vercel-ai": "0.1.4", + "@goat-sdk/core": "0.3.8", + "@goat-sdk/plugin-erc20": "0.1.4", + "@goat-sdk/wallet-viem": "0.1.3", + "ai": "^4.0.3", + "dotenv": "^16.4.5", + "viem": "2.21.49" + } } diff --git a/typescript/examples/vercel-ai/viem/tsconfig.json b/typescript/examples/vercel-ai/viem/tsconfig.json index 6db2f3a9d..a7fc4a937 100644 --- a/typescript/examples/vercel-ai/viem/tsconfig.json +++ b/typescript/examples/vercel-ai/viem/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["index.ts"], - "exclude": ["node_modules", "dist"] + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["index.ts"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/package.json b/typescript/package.json index a2de15d5a..dad724ac7 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,39 +1,39 @@ { - "private": true, - "name": "goat-repo", - "version": "0.1.1", - "scripts": { - "build": "pnpm turbo build", - "clean": "pnpm turbo clean", - "lint": "pnpm biome check --write", - "test": "pnpm turbo test" - }, - "devDependencies": { - "@biomejs/biome": "1.9.4", - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "turbo": "2.3.1", - "vitest": "^2.1.5" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "homepage": "https://github.com/crossmint/goat", - "repository": { - "type": "git", - "url": "git+https://github.com/crossmint/goat.git" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/crossmint/goat/issues" - }, - "keywords": ["ai", "agents", "web3"], - "packageManager": "pnpm@9.14.2", - "workspaces": ["packages/*", "examples/*"] + "private": true, + "name": "goat-repo", + "version": "0.1.1", + "scripts": { + "build": "pnpm turbo build", + "clean": "pnpm turbo clean", + "lint": "pnpm biome check --write", + "test": "pnpm turbo test" + }, + "devDependencies": { + "@biomejs/biome": "1.9.4", + "@types/node": "^22.7.4", + "globals": "^15.12.0", + "ts-node": "^10.9.2", + "tsup": "^8.3.5", + "typescript": "^5.6.3", + "turbo": "2.3.1", + "vitest": "^2.1.5" + }, + "engines": { + "node": ">=20.12.2 <21", + "npm": "please-use-pnpm", + "pnpm": ">=9", + "yarn": "please-use-pnpm" + }, + "homepage": "https://github.com/crossmint/goat", + "repository": { + "type": "git", + "url": "git+https://github.com/crossmint/goat.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/crossmint/goat/issues" + }, + "keywords": ["ai", "agents", "web3"], + "packageManager": "pnpm@9.14.2", + "workspaces": ["packages/*", "examples/*"] } diff --git a/typescript/packages/adapters/eleven-labs/package.json b/typescript/packages/adapters/eleven-labs/package.json index 10096d2bb..3acf748ed 100644 --- a/typescript/packages/adapters/eleven-labs/package.json +++ b/typescript/packages/adapters/eleven-labs/package.json @@ -1,46 +1,31 @@ { - "name": "@goat-sdk/adapter-eleven-labs", - "version": "0.1.2", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "zod": "^3.23.8" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/adapter-eleven-labs", + "version": "0.1.2", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "zod": "^3.23.8" + }, + "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/adapters/eleven-labs/src/index.ts b/typescript/packages/adapters/eleven-labs/src/index.ts index 0ae6d3719..4779099ff 100644 --- a/typescript/packages/adapters/eleven-labs/src/index.ts +++ b/typescript/packages/adapters/eleven-labs/src/index.ts @@ -16,7 +16,7 @@ export type GetOnChainToolsParams = { type ElevenLabsTool = ( // biome-ignore lint/suspicious/noExplicitAny: any is returned by the ElevenLabs tools - parameters: any + parameters: any, // biome-ignore lint/suspicious/noConfusingVoidType: void is returned by the ElevenLabs tools ) => Promise | string | number | void; @@ -37,9 +37,7 @@ export async function getOnChainTools({ } for (const [index, t] of tools.entries()) { - elevenLabsTools[t.name] = async ( - parameters: z.output - ) => { + elevenLabsTools[t.name] = async (parameters: z.output) => { return JSON.stringify(await t.method(parameters)); }; @@ -47,10 +45,7 @@ export async function getOnChainTools({ console.log( `\n${index + 1}. ${t.name}\n\nDescription: ${ t.description - }\n\nParameters:\n${addParametersToDescription( - "", - t.parameters - )}\n` + }\n\nParameters:\n${addParametersToDescription("", t.parameters)}\n`, ); } } diff --git a/typescript/packages/adapters/eleven-labs/tsconfig.json b/typescript/packages/adapters/eleven-labs/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/adapters/eleven-labs/tsconfig.json +++ b/typescript/packages/adapters/eleven-labs/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/adapters/eleven-labs/tsup.config.ts b/typescript/packages/adapters/eleven-labs/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/adapters/eleven-labs/tsup.config.ts +++ b/typescript/packages/adapters/eleven-labs/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/adapters/eleven-labs/turbo.json b/typescript/packages/adapters/eleven-labs/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/adapters/eleven-labs/turbo.json +++ b/typescript/packages/adapters/eleven-labs/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/adapters/eliza/package.json b/typescript/packages/adapters/eliza/package.json index c5f6e195f..829847829 100644 --- a/typescript/packages/adapters/eliza/package.json +++ b/typescript/packages/adapters/eliza/package.json @@ -1,48 +1,33 @@ { - "name": "@goat-sdk/adapter-eliza", - "version": "0.1.5", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@ai16z/eliza": "0.1.4-alpha.3", - "@goat-sdk/core": "workspace:*", - "zod": "^3.23.8" - }, - "peerDependencies": { - "@ai16z/eliza": "0.1.4-alpha.3", - "@goat-sdk/core": "workspace:*" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/adapter-eliza", + "version": "0.1.5", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@ai16z/eliza": "0.1.4-alpha.3", + "@goat-sdk/core": "workspace:*", + "zod": "^3.23.8" + }, + "peerDependencies": { + "@ai16z/eliza": "0.1.4-alpha.3", + "@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/adapters/eliza/src/index.ts b/typescript/packages/adapters/eliza/src/index.ts index 033b8eba5..179e43e5d 100644 --- a/typescript/packages/adapters/eliza/src/index.ts +++ b/typescript/packages/adapters/eliza/src/index.ts @@ -1,15 +1,5 @@ -import { - type WalletClient, - type Plugin, - getDeferredTools, - parametersToJsonExample, - addParametersToDescription, - type ChainForWalletClient, - type DeferredTool, -} from "@goat-sdk/core"; import { type Action, - generateText, type HandlerCallback, type IAgentRuntime, type Memory, @@ -17,7 +7,17 @@ import { type State, composeContext, generateObject, + generateText, } from "@ai16z/eliza"; +import { + type ChainForWalletClient, + type DeferredTool, + type Plugin, + type WalletClient, + addParametersToDescription, + getDeferredTools, + parametersToJsonExample, +} from "@goat-sdk/core"; type GetOnChainActionsParams = { chain: ChainForWalletClient; @@ -44,7 +44,7 @@ export async function getOnChainActions({ function createAction( tool: DeferredTool, - getWalletClient: (runtime: IAgentRuntime) => Promise + getWalletClient: (runtime: IAgentRuntime) => Promise, ): Action { return { name: tool.name.toUpperCase(), @@ -56,24 +56,15 @@ function createAction( message: Memory, state: State | undefined, options?: Record, - callback?: HandlerCallback + callback?: HandlerCallback, ): Promise => { try { const walletClient = await getWalletClient(runtime); - let currentState = - state ?? (await runtime.composeState(message)); - currentState = await runtime.updateRecentMessageState( - currentState - ); - - const parameterContext = composeParameterContext( - tool, - currentState - ); - const parameters = await generateParameters( - runtime, - parameterContext - ); + let currentState = state ?? (await runtime.composeState(message)); + currentState = await runtime.updateRecentMessageState(currentState); + + const parameterContext = composeParameterContext(tool, currentState); + const parameters = await generateParameters(runtime, parameterContext); const parsedParameters = tool.parameters.safeParse(parameters); if (!parsedParameters.success) { @@ -84,25 +75,14 @@ function createAction( return false; } - const result = await tool.method( - walletClient, - parsedParameters.data - ); - const responseContext = composeResponseContext( - tool, - result, - currentState - ); - const response = await generateResponse( - runtime, - responseContext - ); + const result = await tool.method(walletClient, parsedParameters.data); + const responseContext = composeResponseContext(tool, result, currentState); + const response = await generateResponse(runtime, responseContext); callback?.({ text: response, content: result }); return true; } catch (error) { - const errorMessage = - error instanceof Error ? error.message : String(error); + const errorMessage = error instanceof Error ? error.message : String(error); callback?.({ text: `Error executing action ${tool.name}: ${errorMessage}`, content: { error: errorMessage }, @@ -116,7 +96,7 @@ function createAction( function composeParameterContext( tool: DeferredTool, - state: State + state: State, ): string { const contextTemplate = `Respond with a JSON markdown block containing only the extracted values for action "${ tool.name @@ -129,18 +109,13 @@ ${parametersToJsonExample(tool.parameters)} {{recentMessages}} -Given the recent messages, extract the following information for the action "${ - tool.name - }": +Given the recent messages, extract the following information for the action "${tool.name}": ${addParametersToDescription("", tool.parameters)} `; return composeContext({ state, template: contextTemplate }); } -async function generateParameters( - runtime: IAgentRuntime, - context: string -): Promise { +async function generateParameters(runtime: IAgentRuntime, context: string): Promise { return generateObject({ runtime, context, @@ -151,7 +126,7 @@ async function generateParameters( function composeResponseContext( tool: DeferredTool, result: unknown, - state: State + state: State, ): string { const responseTemplate = ` The action "${tool.name}" was executed successfully. @@ -164,10 +139,7 @@ Respond to the message knowing that the action was successful and these were the return composeContext({ state, template: responseTemplate }); } -async function generateResponse( - runtime: IAgentRuntime, - context: string -): Promise { +async function generateResponse(runtime: IAgentRuntime, context: string): Promise { return generateText({ runtime, context, diff --git a/typescript/packages/adapters/eliza/tsconfig.json b/typescript/packages/adapters/eliza/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/adapters/eliza/tsconfig.json +++ b/typescript/packages/adapters/eliza/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/adapters/eliza/tsup.config.ts b/typescript/packages/adapters/eliza/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/adapters/eliza/tsup.config.ts +++ b/typescript/packages/adapters/eliza/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/adapters/eliza/turbo.json b/typescript/packages/adapters/eliza/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/adapters/eliza/turbo.json +++ b/typescript/packages/adapters/eliza/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/adapters/langchain/package.json b/typescript/packages/adapters/langchain/package.json index 6f9975c6b..1108386f9 100644 --- a/typescript/packages/adapters/langchain/package.json +++ b/typescript/packages/adapters/langchain/package.json @@ -1,48 +1,33 @@ { - "name": "@goat-sdk/adapter-langchain", - "version": "0.1.4", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "@langchain/core": "^0.3.6", - "zod": "^3.23.8" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*", - "@langchain/core": "^0.3.6" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/adapter-langchain", + "version": "0.1.4", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "@langchain/core": "^0.3.6", + "zod": "^3.23.8" + }, + "peerDependencies": { + "@goat-sdk/core": "workspace:*", + "@langchain/core": "^0.3.6" + }, + "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/adapters/langchain/src/index.ts b/typescript/packages/adapters/langchain/src/index.ts index 00cb1f23a..7b6a05272 100644 --- a/typescript/packages/adapters/langchain/src/index.ts +++ b/typescript/packages/adapters/langchain/src/index.ts @@ -1,33 +1,32 @@ import { - type GetToolsParams, - type Tool, - type WalletClient, - addParametersToDescription, - getTools, + type GetToolsParams, + type Tool, + type WalletClient, + addParametersToDescription, + getTools, } from "@goat-sdk/core"; import { tool } from "@langchain/core/tools"; import type { z } from "zod"; -export type GetOnChainToolsParams = - GetToolsParams; +export type GetOnChainToolsParams = GetToolsParams; export async function getOnChainTools({ - wallet, - plugins, + wallet, + plugins, }: GetOnChainToolsParams) { - const tools: Tool[] = await getTools({ wallet, plugins }); + const tools: Tool[] = await getTools({ wallet, plugins }); - return tools.map((t) => - tool( - async (arg: z.output) => { - return await t.method(arg); - }, - { - name: t.name, - description: addParametersToDescription(t.description, t.parameters), - schema: t.parameters, - }, - ), - ); + return tools.map((t) => + tool( + async (arg: z.output) => { + return await t.method(arg); + }, + { + name: t.name, + description: addParametersToDescription(t.description, t.parameters), + schema: t.parameters, + }, + ), + ); } diff --git a/typescript/packages/adapters/langchain/tsconfig.json b/typescript/packages/adapters/langchain/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/adapters/langchain/tsconfig.json +++ b/typescript/packages/adapters/langchain/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/adapters/langchain/tsup.config.ts b/typescript/packages/adapters/langchain/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/adapters/langchain/tsup.config.ts +++ b/typescript/packages/adapters/langchain/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/adapters/langchain/turbo.json b/typescript/packages/adapters/langchain/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/adapters/langchain/turbo.json +++ b/typescript/packages/adapters/langchain/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/adapters/vercel-ai/package.json b/typescript/packages/adapters/vercel-ai/package.json index eca2ad880..b78ee5f34 100644 --- a/typescript/packages/adapters/vercel-ai/package.json +++ b/typescript/packages/adapters/vercel-ai/package.json @@ -1,48 +1,33 @@ { - "name": "@goat-sdk/adapter-vercel-ai", - "version": "0.1.4", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "ai": "^4.0.3", - "zod": "^3.23.8" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*", - "ai": "^4.0.3" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/adapter-vercel-ai", + "version": "0.1.4", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "ai": "^4.0.3", + "zod": "^3.23.8" + }, + "peerDependencies": { + "@goat-sdk/core": "workspace:*", + "ai": "^4.0.3" + }, + "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/adapters/vercel-ai/src/index.ts b/typescript/packages/adapters/vercel-ai/src/index.ts index b1d125ad7..81e8491e6 100644 --- a/typescript/packages/adapters/vercel-ai/src/index.ts +++ b/typescript/packages/adapters/vercel-ai/src/index.ts @@ -2,36 +2,35 @@ import { type GetToolsParams, type Tool, type WalletClient, - getTools, addParametersToDescription, + getTools, } from "@goat-sdk/core"; import { type CoreTool, tool } from "ai"; import type { z } from "zod"; -export type GetOnChainToolsParams = - GetToolsParams; +export type GetOnChainToolsParams = GetToolsParams; export async function getOnChainTools({ - wallet, - plugins, + wallet, + plugins, }: GetOnChainToolsParams) { - const tools: Tool[] = await getTools({ + const tools: Tool[] = await getTools({ wallet, plugins, }); - const aiTools: { [key: string]: CoreTool } = {}; + const aiTools: { [key: string]: CoreTool } = {}; - for (const t of tools) { - aiTools[t.name] = tool({ - description: addParametersToDescription(t.description, t.parameters), - parameters: t.parameters, - execute: async (arg: z.output) => { - return await t.method(arg); - }, - }); - } + for (const t of tools) { + aiTools[t.name] = tool({ + description: addParametersToDescription(t.description, t.parameters), + parameters: t.parameters, + execute: async (arg: z.output) => { + return await t.method(arg); + }, + }); + } - return aiTools; + return aiTools; } diff --git a/typescript/packages/adapters/vercel-ai/tsconfig.json b/typescript/packages/adapters/vercel-ai/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/adapters/vercel-ai/tsconfig.json +++ b/typescript/packages/adapters/vercel-ai/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/adapters/vercel-ai/tsup.config.ts b/typescript/packages/adapters/vercel-ai/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/adapters/vercel-ai/tsup.config.ts +++ b/typescript/packages/adapters/vercel-ai/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/adapters/vercel-ai/turbo.json b/typescript/packages/adapters/vercel-ai/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/adapters/vercel-ai/turbo.json +++ b/typescript/packages/adapters/vercel-ai/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/core/package.json b/typescript/packages/core/package.json index 5239476fb..7af06d5d5 100644 --- a/typescript/packages/core/package.json +++ b/typescript/packages/core/package.json @@ -1,45 +1,30 @@ { - "name": "@goat-sdk/core", - "version": "0.3.10", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@solana/web3.js": "1.95.8", - "abitype": "^1.0.6", - "viem": "^2.21.49", - "zod": "^3.23.8" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/core", + "version": "0.3.10", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@solana/web3.js": "1.95.8", + "abitype": "^1.0.6", + "viem": "^2.21.49", + "zod": "^3.23.8" + }, + "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/core/src/evm/methods.ts b/typescript/packages/core/src/evm/methods.ts index d07733535..be7f56701 100644 --- a/typescript/packages/core/src/evm/methods.ts +++ b/typescript/packages/core/src/evm/methods.ts @@ -1,31 +1,26 @@ import { formatUnits } from "viem"; import type { z } from "zod"; import type { EVMWalletClient } from "../wallets"; -import type { - getAddressParametersSchema, - getETHBalanceParametersSchema, -} from "./parameters"; +import type { getAddressParametersSchema, getETHBalanceParametersSchema } from "./parameters"; export function getAddress( - walletClient: EVMWalletClient, - parameters: z.infer, + walletClient: EVMWalletClient, + parameters: z.infer, ): string { - return walletClient.getAddress(); + return walletClient.getAddress(); } export async function getBalance( - walletClient: EVMWalletClient, - parameters: z.infer, + walletClient: EVMWalletClient, + parameters: z.infer, ): Promise { - try { - const address = await walletClient.resolveAddress( - parameters.address ?? getAddress(walletClient, {}), - ); + try { + const address = await walletClient.resolveAddress(parameters.address ?? getAddress(walletClient, {})); - const balance = await walletClient.balanceOf(address.toString()); + const balance = await walletClient.balanceOf(address.toString()); - return formatUnits(balance.value, balance.decimals); - } catch (error) { - throw new Error(`Failed to fetch balance: ${error}`); - } + return formatUnits(balance.value, balance.decimals); + } catch (error) { + throw new Error(`Failed to fetch balance: ${error}`); + } } diff --git a/typescript/packages/core/src/evm/parameters.ts b/typescript/packages/core/src/evm/parameters.ts index 6c943310f..2fe396217 100644 --- a/typescript/packages/core/src/evm/parameters.ts +++ b/typescript/packages/core/src/evm/parameters.ts @@ -3,5 +3,7 @@ import { z } from "zod"; export const getAddressParametersSchema = z.object({}); export const getETHBalanceParametersSchema = z.object({ - address: z.optional(z.string()).describe("The address to get the balance of, defaults to the address of the wallet"), + address: z + .optional(z.string()) + .describe("The address to get the balance of, defaults to the address of the wallet"), }); diff --git a/typescript/packages/core/src/evm/tools.ts b/typescript/packages/core/src/evm/tools.ts index 7fe34d881..b768f5978 100644 --- a/typescript/packages/core/src/evm/tools.ts +++ b/typescript/packages/core/src/evm/tools.ts @@ -1,10 +1,7 @@ import type { DeferredTool } from "../tools"; import type { AnyEVMWalletClient } from "../wallets"; import { getAddress, getBalance } from "./methods"; -import { - getAddressParametersSchema, - getETHBalanceParametersSchema, -} from "./parameters"; +import { getAddressParametersSchema, getETHBalanceParametersSchema } from "./parameters"; export const deferredEVMCoreTools: DeferredTool[] = [ { diff --git a/typescript/packages/core/src/index.ts b/typescript/packages/core/src/index.ts index 0235ec694..af19de99b 100644 --- a/typescript/packages/core/src/index.ts +++ b/typescript/packages/core/src/index.ts @@ -2,17 +2,18 @@ import type { Plugin } from "./plugins/plugins"; import { sendETH } from "./plugins/send-eth"; import { sendSOL } from "./plugins/send-sol"; import { + type DeferredTool, + type GetDeferredToolsParams, type GetToolsParams, type Tool, - getTools, - type DeferredTool, getDeferredTools, - type GetDeferredToolsParams, + getTools, } from "./tools"; -import { addParametersToDescription, parametersToJsonExample} from "./utils"; +import { addParametersToDescription, parametersToJsonExample } from "./utils"; import type { Balance, Chain, + ChainForWalletClient, EVMReadRequest, EVMSmartWalletClient, EVMTransaction, @@ -26,7 +27,6 @@ import type { isEVMSmartWalletClient, isEVMWalletClient, isSolanaWalletClient, - ChainForWalletClient } from "./wallets"; export { diff --git a/typescript/packages/core/src/plugins/plugins.ts b/typescript/packages/core/src/plugins/plugins.ts index d6a7b81cb..d4fdf993c 100644 --- a/typescript/packages/core/src/plugins/plugins.ts +++ b/typescript/packages/core/src/plugins/plugins.ts @@ -15,7 +15,5 @@ export interface Plugin { name: string; supportsChain: (chain: Chain) => boolean; supportsSmartWallets: () => boolean; - getTools: ( - chain: ChainForWalletClient - ) => Promise[]>; + getTools: (chain: ChainForWalletClient) => Promise[]>; } diff --git a/typescript/packages/core/src/plugins/send-eth.ts b/typescript/packages/core/src/plugins/send-eth.ts index 85b50c948..70b060046 100644 --- a/typescript/packages/core/src/plugins/send-eth.ts +++ b/typescript/packages/core/src/plugins/send-eth.ts @@ -1,7 +1,7 @@ import { parseEther } from "viem"; +import { z } from "zod"; import type { EVMWalletClient } from "../wallets"; import type { Plugin } from "./plugins"; -import { z } from "zod"; export function sendETH(): Plugin { return { @@ -12,8 +12,7 @@ export function sendETH(): Plugin { return [ { name: "send_eth", - description: - "This {{tool}} sends ETH to an address on an EVM chain.", + description: "This {{tool}} sends ETH to an address on an EVM chain.", parameters: sendETHParametersSchema, method: sendETHMethod, }, @@ -27,10 +26,9 @@ const sendETHParametersSchema = z.object({ amount: z.string().describe("The amount of ETH to send"), }); - async function sendETHMethod( walletClient: EVMWalletClient, - parameters: z.infer + parameters: z.infer, ): Promise { try { const amount = parseEther(parameters.amount); diff --git a/typescript/packages/core/src/plugins/send-sol.ts b/typescript/packages/core/src/plugins/send-sol.ts index 0594eab43..4d9de23ed 100644 --- a/typescript/packages/core/src/plugins/send-sol.ts +++ b/typescript/packages/core/src/plugins/send-sol.ts @@ -1,9 +1,9 @@ import { PublicKey } from "@solana/web3.js"; +import { SystemProgram } from "@solana/web3.js"; import { parseUnits } from "viem"; +import { z } from "zod"; import type { SolanaWalletClient } from "../wallets"; import type { Plugin } from "./plugins"; -import { z } from "zod"; -import { SystemProgram } from "@solana/web3.js"; export function sendSOL(): Plugin { return { @@ -14,8 +14,7 @@ export function sendSOL(): Plugin { return [ { name: "send_sol", - description: - "This {{tool}} sends SOL to an address on a Solana chain.", + description: "This {{tool}} sends SOL to an address on a Solana chain.", parameters: sendSOLParametersSchema, method: sendSOLMethod, }, @@ -31,7 +30,7 @@ const sendSOLParametersSchema = z.object({ async function sendSOLMethod( walletClient: SolanaWalletClient, - parameters: z.infer + parameters: z.infer, ): Promise { try { const { to, amount } = parameters; diff --git a/typescript/packages/core/src/solana/methods.ts b/typescript/packages/core/src/solana/methods.ts index b3f90e1ab..c264c01f7 100644 --- a/typescript/packages/core/src/solana/methods.ts +++ b/typescript/packages/core/src/solana/methods.ts @@ -1,29 +1,24 @@ import { formatUnits } from "viem"; import type { z } from "zod"; import type { SolanaWalletClient } from "../wallets"; -import type { - getAddressParametersSchema, - getSOLBalanceParametersSchema, -} from "./parameters"; +import type { getAddressParametersSchema, getSOLBalanceParametersSchema } from "./parameters"; export function getAddress( - walletClient: SolanaWalletClient, - parameters: z.infer, + walletClient: SolanaWalletClient, + parameters: z.infer, ): string { - return walletClient.getAddress(); + return walletClient.getAddress(); } export async function getBalance( - walletClient: SolanaWalletClient, - parameters: z.infer, + walletClient: SolanaWalletClient, + parameters: z.infer, ): Promise { - try { - const balance = await walletClient.balanceOf( - parameters.address ?? getAddress(walletClient, {}), - ); + try { + const balance = await walletClient.balanceOf(parameters.address ?? getAddress(walletClient, {})); - return formatUnits(balance.value, balance.decimals); - } catch (error) { - throw new Error(`Failed to fetch balance: ${error}`); - } + return formatUnits(balance.value, balance.decimals); + } catch (error) { + throw new Error(`Failed to fetch balance: ${error}`); + } } diff --git a/typescript/packages/core/src/solana/parameters.ts b/typescript/packages/core/src/solana/parameters.ts index 18a255576..78ef584e8 100644 --- a/typescript/packages/core/src/solana/parameters.ts +++ b/typescript/packages/core/src/solana/parameters.ts @@ -3,5 +3,7 @@ import { z } from "zod"; export const getAddressParametersSchema = z.object({}); export const getSOLBalanceParametersSchema = z.object({ - address: z.optional(z.string()).describe("The address to get the balance of, defaults to the address of the wallet"), + address: z + .optional(z.string()) + .describe("The address to get the balance of, defaults to the address of the wallet"), }); diff --git a/typescript/packages/core/src/solana/tools.ts b/typescript/packages/core/src/solana/tools.ts index 6afb01cd4..547b9284f 100644 --- a/typescript/packages/core/src/solana/tools.ts +++ b/typescript/packages/core/src/solana/tools.ts @@ -1,10 +1,7 @@ import type { DeferredTool } from "../tools"; import type { SolanaWalletClient } from "../wallets"; import { getAddress, getBalance } from "./methods"; -import { - getAddressParametersSchema, - getSOLBalanceParametersSchema, -} from "./parameters"; +import { getAddressParametersSchema, getSOLBalanceParametersSchema } from "./parameters"; export const deferredSolanaTools: DeferredTool[] = [ { @@ -15,8 +12,7 @@ export const deferredSolanaTools: DeferredTool[] = [ }, { name: "get_sol_balance", - description: - "This {{tool}} returns the SOL balance of a Solana wallet.", + description: "This {{tool}} returns the SOL balance of a Solana wallet.", parameters: getSOLBalanceParametersSchema, method: getBalance, }, diff --git a/typescript/packages/core/src/tools.ts b/typescript/packages/core/src/tools.ts index 8e1f4633d..3edcde82e 100644 --- a/typescript/packages/core/src/tools.ts +++ b/typescript/packages/core/src/tools.ts @@ -2,8 +2,8 @@ import type { z } from "zod"; import { deferredEVMCoreTools } from "./evm/tools"; import type { Plugin } from "./plugins/plugins"; import { deferredSolanaTools } from "./solana/tools"; -import type { WalletClient, ChainForWalletClient, AnyEVMWalletClient } from "./wallets"; import { replaceToolPlaceholder } from "./utils"; +import type { AnyEVMWalletClient, ChainForWalletClient, WalletClient } from "./wallets"; import { isEVMChain, isEVMSmartWalletClient, isSolanaChain } from "./wallets"; export type Tool = { @@ -26,13 +26,12 @@ export async function getTools({ }: GetToolsParams): Promise { const chain = wallet.getChain() as ChainForWalletClient; - const tools: DeferredTool[] = - await getDeferredTools({ - chain, - plugins, - supportsSmartWallets: isEVMSmartWalletClient(wallet), - wordForTool, - }); + const tools: DeferredTool[] = await getDeferredTools({ + chain, + plugins, + supportsSmartWallets: isEVMSmartWalletClient(wallet), + wordForTool, + }); return tools.map((tool) => ({ ...tool, @@ -47,10 +46,7 @@ export type DeferredTool = { name: string; description: string; parameters: z.ZodSchema; - method: ( - walletClient: TWalletClient, - parameters: z.infer - ) => string | Promise; + method: (walletClient: TWalletClient, parameters: z.infer) => string | Promise; }; export type GetDeferredToolsParams = { @@ -60,44 +56,32 @@ export type GetDeferredToolsParams = { wordForTool?: string; }; -export async function getDeferredTools< - TWalletClient extends AnyEVMWalletClient | WalletClient ->({ +export async function getDeferredTools({ chain, supportsSmartWallets = false, wordForTool = "tool", plugins = [], -}: GetDeferredToolsParams): Promise< - DeferredTool[] -> { +}: GetDeferredToolsParams): Promise[]> { const tools: DeferredTool[] = []; if (isEVMChain(chain)) { // We know that TWalletClient is compatible with EVMWalletClient here - tools.push( - ...(deferredEVMCoreTools as unknown as DeferredTool[]) - ); + tools.push(...(deferredEVMCoreTools as unknown as DeferredTool[])); } else if (isSolanaChain(chain)) { // We know that TWalletClient is compatible with SolanaWalletClient here - tools.push( - ...(deferredSolanaTools as unknown as DeferredTool[]) - ); + tools.push(...(deferredSolanaTools as unknown as DeferredTool[])); } else { throw new Error(`Unsupported chain type: ${chain.type}`); } for (const plugin of plugins) { if (!plugin.supportsChain(chain)) { - console.warn( - `Plugin ${plugin.name} does not support chain ${chain.type}. Skipping.` - ); + console.warn(`Plugin ${plugin.name} does not support chain ${chain.type}. Skipping.`); continue; } if (!plugin.supportsSmartWallets() && supportsSmartWallets) { - console.warn( - `Plugin ${plugin.name} does not support smart wallets. Skipping.` - ); + console.warn(`Plugin ${plugin.name} does not support smart wallets. Skipping.`); continue; } diff --git a/typescript/packages/core/src/utils.ts b/typescript/packages/core/src/utils.ts index d2d102c28..9815ede67 100644 --- a/typescript/packages/core/src/utils.ts +++ b/typescript/packages/core/src/utils.ts @@ -1,10 +1,7 @@ import type { ZodTypeAny } from "zod"; import { z } from "zod"; -export function addParametersToDescription( - description: string, - schema: z.ZodTypeAny -): string { +export function addParametersToDescription(description: string, schema: z.ZodTypeAny): string { let paramLines: string[] = []; if (schema instanceof z.ZodObject) { @@ -14,20 +11,14 @@ export function addParametersToDescription( const paramDescription = value.description || ""; const typeStr = getTypeString(value); - return `- ${key}${ - isOptional ? " (optional)" : "" - } (${typeStr}): ${paramDescription}`; + return `- ${key}${isOptional ? " (optional)" : ""} (${typeStr}): ${paramDescription}`; }); } else { const isOptional = schema.isOptional(); const paramDescription = schema.description || ""; const typeStr = getTypeString(schema); - paramLines.push( - `- ${ - isOptional ? "(optional) " : "" - }(${typeStr}): ${paramDescription}` - ); + paramLines.push(`- ${isOptional ? "(optional) " : ""}(${typeStr}): ${paramDescription}`); } return `${description}\n${paramLines.join("\n")}`; @@ -56,10 +47,7 @@ function getTypeString(schema: z.ZodTypeAny): string { return "unknown"; } -export function replaceToolPlaceholder( - template: string, - wordForTool = "tool" -): string { +export function replaceToolPlaceholder(template: string, wordForTool = "tool"): string { const placeholderRegex = /\{\{\s*tool\s*\}\}/g; return template.replace(placeholderRegex, wordForTool); } @@ -90,10 +78,7 @@ export function parametersToJsonExample(parameters: z.ZodTypeAny): string { } return obj; } - if ( - schema instanceof z.ZodOptional || - schema instanceof z.ZodNullable - ) { + if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable) { const innerSchema = schema.unwrap(); return generateExample(innerSchema); } diff --git a/typescript/packages/core/src/wallets/core.ts b/typescript/packages/core/src/wallets/core.ts index 0cc0a8538..c0448df5d 100644 --- a/typescript/packages/core/src/wallets/core.ts +++ b/typescript/packages/core/src/wallets/core.ts @@ -1,12 +1,12 @@ export type Signature = { - signature: string; + signature: string; }; export type Balance = { - decimals: number; - symbol: string; - name: string; - value: bigint; + decimals: number; + symbol: string; + name: string; + value: bigint; }; /** @@ -14,21 +14,21 @@ export type Balance = { * @param id - Chain ID, optional for EVM */ export type Chain = { - type: "evm" | "solana"; - id?: number; // optional for EVM + type: "evm" | "solana"; + id?: number; // optional for EVM }; export type EVMChain = Chain & { - type: "evm"; + type: "evm"; }; export type SolanaChain = Chain & { - type: "solana"; + type: "solana"; }; export interface WalletClient { - getAddress: () => string; - getChain: () => Chain; - signMessage: (message: string) => Promise; - balanceOf: (address: string) => Promise; + getAddress: () => string; + getChain: () => Chain; + signMessage: (message: string) => Promise; + balanceOf: (address: string) => Promise; } diff --git a/typescript/packages/core/src/wallets/evm-smart-wallet.ts b/typescript/packages/core/src/wallets/evm-smart-wallet.ts index cf35bfa44..b86e93e96 100644 --- a/typescript/packages/core/src/wallets/evm-smart-wallet.ts +++ b/typescript/packages/core/src/wallets/evm-smart-wallet.ts @@ -1,22 +1,11 @@ import type { WalletClient } from "./core"; -import type { - EVMTransaction, - EVMTransactionResult, - EVMWalletClient, -} from "./evm"; +import type { EVMTransaction, EVMTransactionResult, EVMWalletClient } from "./evm"; -export function isEVMSmartWalletClient( - wallet: WalletClient, -): wallet is EVMSmartWalletClient { - return ( - typeof (wallet as EVMSmartWalletClient).sendBatchOfTransactions === - "function" - ); +export function isEVMSmartWalletClient(wallet: WalletClient): wallet is EVMSmartWalletClient { + return typeof (wallet as EVMSmartWalletClient).sendBatchOfTransactions === "function"; } export interface EVMSmartWalletClient extends EVMWalletClient { - sendBatchOfTransactions: ( - transactions: EVMTransaction[], - ) => Promise; + sendBatchOfTransactions: (transactions: EVMTransaction[]) => Promise; } diff --git a/typescript/packages/core/src/wallets/evm.ts b/typescript/packages/core/src/wallets/evm.ts index 86451a985..bb73bdaac 100644 --- a/typescript/packages/core/src/wallets/evm.ts +++ b/typescript/packages/core/src/wallets/evm.ts @@ -1,50 +1,46 @@ import type { Abi, TypedDataDomain as AbiTypedDataDomainType } from "abitype"; import type { Signature, WalletClient } from "./core"; -export function isEVMWalletClient( - wallet: WalletClient, -): wallet is EVMWalletClient { - return wallet.getChain().type === "evm"; +export function isEVMWalletClient(wallet: WalletClient): wallet is EVMWalletClient { + return wallet.getChain().type === "evm"; } export type EVMTransaction = { - to: string; - functionName?: string; - args?: unknown[]; - value?: bigint; - abi?: Abi; + to: string; + functionName?: string; + args?: unknown[]; + value?: bigint; + abi?: Abi; }; export type EVMReadRequest = { - address: string; - functionName: string; - args?: unknown[]; - abi: Abi; + address: string; + functionName: string; + args?: unknown[]; + abi: Abi; }; export type EVMTransactionResult = { - hash: string; - status: string; + hash: string; + status: string; }; export type EVMReadResult = { - value: unknown; + value: unknown; }; export type EVMTypedData = { - domain: TypedDataDomain; - types: Record; - primaryType: string; - message: Record; + domain: TypedDataDomain; + types: Record; + primaryType: string; + message: Record; }; export type TypedDataDomain = AbiTypedDataDomainType; export interface EVMWalletClient extends WalletClient { - sendTransaction: ( - transaction: EVMTransaction, - ) => Promise; - read: (request: EVMReadRequest) => Promise; - resolveAddress: (address: string) => Promise<`0x${string}`>; - signTypedData: (data: EVMTypedData) => Promise; + sendTransaction: (transaction: EVMTransaction) => Promise; + read: (request: EVMReadRequest) => Promise; + resolveAddress: (address: string) => Promise<`0x${string}`>; + signTypedData: (data: EVMTypedData) => Promise; } diff --git a/typescript/packages/core/src/wallets/index.ts b/typescript/packages/core/src/wallets/index.ts index 90bb5b9ae..469678448 100644 --- a/typescript/packages/core/src/wallets/index.ts +++ b/typescript/packages/core/src/wallets/index.ts @@ -5,10 +5,7 @@ import { type EVMWalletClient, isEVMWalletClient, } from "./evm"; -import { - type EVMSmartWalletClient, - isEVMSmartWalletClient, -} from "./evm-smart-wallet"; +import { type EVMSmartWalletClient, isEVMSmartWalletClient } from "./evm-smart-wallet"; import { type SolanaReadRequest, type SolanaTransaction, @@ -17,12 +14,7 @@ import { } from "./solana"; import type { Balance, Chain, Signature, WalletClient } from "./core"; -import { - type ChainForWalletClient, - isEVMChain, - isSolanaChain, - type AnyEVMWalletClient, -} from "./utils"; +import { type AnyEVMWalletClient, type ChainForWalletClient, isEVMChain, isSolanaChain } from "./utils"; export type { EVMWalletClient, diff --git a/typescript/packages/core/src/wallets/solana.ts b/typescript/packages/core/src/wallets/solana.ts index 4232321e0..6c574ece1 100644 --- a/typescript/packages/core/src/wallets/solana.ts +++ b/typescript/packages/core/src/wallets/solana.ts @@ -1,31 +1,27 @@ import type { TransactionInstruction } from "@solana/web3.js"; import type { WalletClient } from "./core"; -export function isSolanaWalletClient( - wallet: WalletClient, -): wallet is SolanaWalletClient { - return wallet.getChain().type === "solana"; +export function isSolanaWalletClient(wallet: WalletClient): wallet is SolanaWalletClient { + return wallet.getChain().type === "solana"; } export type SolanaTransaction = { - instructions: TransactionInstruction[]; + instructions: TransactionInstruction[]; }; export type SolanaReadRequest = { - accountAddress: string; + accountAddress: string; }; export type SolanaReadResult = { - value: unknown; + value: unknown; }; export type SolanaTransactionResult = { - hash: string; + hash: string; }; export interface SolanaWalletClient extends WalletClient { - sendTransaction: ( - transaction: SolanaTransaction, - ) => Promise; - read: (request: SolanaReadRequest) => Promise; + sendTransaction: (transaction: SolanaTransaction) => Promise; + read: (request: SolanaReadRequest) => Promise; } diff --git a/typescript/packages/core/src/wallets/utils.ts b/typescript/packages/core/src/wallets/utils.ts index ae1c82138..9e2e1e05b 100644 --- a/typescript/packages/core/src/wallets/utils.ts +++ b/typescript/packages/core/src/wallets/utils.ts @@ -1,14 +1,13 @@ -import type { EVMWalletClient } from "./evm"; -import type { SolanaWalletClient } from "./solana"; import type { Chain, EVMChain, SolanaChain, WalletClient } from "./core"; +import type { EVMWalletClient } from "./evm"; import type { EVMSmartWalletClient } from "./evm-smart-wallet"; +import type { SolanaWalletClient } from "./solana"; -export type ChainForWalletClient = - TWalletClient extends EVMWalletClient - ? EVMChain - : TWalletClient extends SolanaWalletClient - ? SolanaChain - : Chain; +export type ChainForWalletClient = TWalletClient extends EVMWalletClient + ? EVMChain + : TWalletClient extends SolanaWalletClient + ? SolanaChain + : Chain; export function isEVMChain(chain: Chain): chain is EVMChain { return chain.type === "evm"; diff --git a/typescript/packages/core/tsconfig.json b/typescript/packages/core/tsconfig.json index 6afb29f3e..74d626c0d 100644 --- a/typescript/packages/core/tsconfig.json +++ b/typescript/packages/core/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/core/tsup.config.ts b/typescript/packages/core/tsup.config.ts index da5fa3085..12c02a823 100644 --- a/typescript/packages/core/tsup.config.ts +++ b/typescript/packages/core/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/core/turbo.json b/typescript/packages/core/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/core/turbo.json +++ b/typescript/packages/core/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/plugins/erc20/package.json b/typescript/packages/plugins/erc20/package.json index 2292a4f28..4f64d63ad 100644 --- a/typescript/packages/plugins/erc20/package.json +++ b/typescript/packages/plugins/erc20/package.json @@ -1,48 +1,33 @@ { - "name": "@goat-sdk/plugin-erc20", - "version": "0.1.7", - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "sideEffects": false, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "viem": "^2.21.49", - "zod": "^3.23.8" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*", - "viem": "^2.21.49" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/plugin-erc20", + "version": "0.1.7", + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "sideEffects": false, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "viem": "^2.21.49", + "zod": "^3.23.8" + }, + "peerDependencies": { + "@goat-sdk/core": "workspace:*", + "viem": "^2.21.49" + }, + "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/erc20/src/index.ts b/typescript/packages/plugins/erc20/src/index.ts index d337ca5b6..62fa670c4 100644 --- a/typescript/packages/plugins/erc20/src/index.ts +++ b/typescript/packages/plugins/erc20/src/index.ts @@ -6,23 +6,23 @@ export type { Token }; export { USDC, PEPE }; export type ERC20Options = { - tokens: Token[]; + tokens: Token[]; }; export function erc20({ tokens }: ERC20Options): Plugin { - return { - name: "ERC20", - supportsChain: (chain: Chain) => chain.type === "evm", - supportsSmartWallets: () => true, - getTools: async (chain: Chain) => { - const network = chain; + return { + name: "ERC20", + supportsChain: (chain: Chain) => chain.type === "evm", + supportsSmartWallets: () => true, + getTools: async (chain: Chain) => { + const network = chain; - if (!network.id) { - throw new Error("Network ID is required"); - } + if (!network.id) { + throw new Error("Network ID is required"); + } - const tokenList = getTokensForNetwork(network.id, tokens); - return getTools(tokenList); - }, - }; + const tokenList = getTokensForNetwork(network.id, tokens); + return getTools(tokenList); + }, + }; } diff --git a/typescript/packages/plugins/erc20/src/methods.ts b/typescript/packages/plugins/erc20/src/methods.ts index 61d4d4115..a2c0cf450 100644 --- a/typescript/packages/plugins/erc20/src/methods.ts +++ b/typescript/packages/plugins/erc20/src/methods.ts @@ -3,154 +3,139 @@ import { formatUnits, parseUnits } from "viem"; import type { z } from "zod"; import { ERC20_ABI } from "./abi"; import type { - allowanceParametersSchema, - approveParametersSchema, - getBalanceParametersSchema, - transferFromParametersSchema, - transferParametersSchema, + allowanceParametersSchema, + approveParametersSchema, + getBalanceParametersSchema, + transferFromParametersSchema, + transferParametersSchema, } from "./parameters"; import type { ChainSpecificToken } from "./token"; export async function balanceOf( - walletClient: EVMWalletClient, - token: ChainSpecificToken, - parameters: z.infer, + walletClient: EVMWalletClient, + token: ChainSpecificToken, + parameters: z.infer, ): Promise { - try { - const resolvedWalletAddress = await walletClient.resolveAddress( - parameters.wallet, - ); - - const rawBalance = await walletClient.read({ - address: token.contractAddress, - abi: ERC20_ABI, - functionName: "balanceOf", - args: [resolvedWalletAddress], - }); - - return formatUnits(rawBalance.value as bigint, token.decimals); - } catch (error) { - throw Error(`Failed to fetch balance: ${error}`); - } + try { + const resolvedWalletAddress = await walletClient.resolveAddress(parameters.wallet); + + const rawBalance = await walletClient.read({ + address: token.contractAddress, + abi: ERC20_ABI, + functionName: "balanceOf", + args: [resolvedWalletAddress], + }); + + return formatUnits(rawBalance.value as bigint, token.decimals); + } catch (error) { + throw Error(`Failed to fetch balance: ${error}`); + } } export async function transfer( - walletClient: EVMWalletClient, - token: ChainSpecificToken, - parameters: z.infer, + walletClient: EVMWalletClient, + token: ChainSpecificToken, + parameters: z.infer, ): Promise { - try { - const amountInBaseUnits = parseUnits(parameters.amount, token.decimals); - - const resolvedRecipientAddress = await walletClient.resolveAddress( - parameters.to, - ); - - const hash = await walletClient.sendTransaction({ - to: token.contractAddress, - abi: ERC20_ABI, - functionName: "transfer", - args: [resolvedRecipientAddress, amountInBaseUnits], - }); - - return hash.hash; - } catch (error) { - throw Error(`Failed to transfer: ${error}`); - } + try { + const amountInBaseUnits = parseUnits(parameters.amount, token.decimals); + + const resolvedRecipientAddress = await walletClient.resolveAddress(parameters.to); + + const hash = await walletClient.sendTransaction({ + to: token.contractAddress, + abi: ERC20_ABI, + functionName: "transfer", + args: [resolvedRecipientAddress, amountInBaseUnits], + }); + + return hash.hash; + } catch (error) { + throw Error(`Failed to transfer: ${error}`); + } } -export async function totalSupply( - walletClient: EVMWalletClient, - token: ChainSpecificToken, -): Promise { - try { - const rawTotalSupply = await walletClient.read({ - address: token.contractAddress, - abi: ERC20_ABI, - functionName: "totalSupply", - }); - - return formatUnits(rawTotalSupply.value as bigint, token.decimals); - } catch (error) { - throw Error(`Failed to fetch total supply: ${error}`); - } +export async function totalSupply(walletClient: EVMWalletClient, token: ChainSpecificToken): Promise { + try { + const rawTotalSupply = await walletClient.read({ + address: token.contractAddress, + abi: ERC20_ABI, + functionName: "totalSupply", + }); + + return formatUnits(rawTotalSupply.value as bigint, token.decimals); + } catch (error) { + throw Error(`Failed to fetch total supply: ${error}`); + } } export async function allowance( - walletClient: EVMWalletClient, - token: ChainSpecificToken, - parameters: z.infer, + walletClient: EVMWalletClient, + token: ChainSpecificToken, + parameters: z.infer, ): Promise { - try { - const resolvedOwnerAddress = await walletClient.resolveAddress( - parameters.owner, - ); - - const resolvedSpenderAddress = await walletClient.resolveAddress( - parameters.spender, - ); - - const rawAllowance = await walletClient.read({ - address: token.contractAddress, - abi: ERC20_ABI, - functionName: "allowance", - args: [resolvedOwnerAddress, resolvedSpenderAddress], - }); - - return formatUnits(rawAllowance.value as bigint, token.decimals); - } catch (error) { - throw Error(`Failed to fetch allowance: ${error}`); - } + try { + const resolvedOwnerAddress = await walletClient.resolveAddress(parameters.owner); + + const resolvedSpenderAddress = await walletClient.resolveAddress(parameters.spender); + + const rawAllowance = await walletClient.read({ + address: token.contractAddress, + abi: ERC20_ABI, + functionName: "allowance", + args: [resolvedOwnerAddress, resolvedSpenderAddress], + }); + + return formatUnits(rawAllowance.value as bigint, token.decimals); + } catch (error) { + throw Error(`Failed to fetch allowance: ${error}`); + } } export async function approve( - walletClient: EVMWalletClient, - token: ChainSpecificToken, - parameters: z.infer, + walletClient: EVMWalletClient, + token: ChainSpecificToken, + parameters: z.infer, ): Promise { - try { - const resolvedSpenderAddress = await walletClient.resolveAddress( - parameters.spender, - ); - - const amountInBaseUnits = parseUnits(parameters.amount, token.decimals); - - const hash = await walletClient.sendTransaction({ - to: token.contractAddress, - abi: ERC20_ABI, - functionName: "approve", - args: [resolvedSpenderAddress, amountInBaseUnits], - }); - - return hash.hash; - } catch (error) { - throw Error(`Failed to approve: ${error}`); - } + try { + const resolvedSpenderAddress = await walletClient.resolveAddress(parameters.spender); + + const amountInBaseUnits = parseUnits(parameters.amount, token.decimals); + + const hash = await walletClient.sendTransaction({ + to: token.contractAddress, + abi: ERC20_ABI, + functionName: "approve", + args: [resolvedSpenderAddress, amountInBaseUnits], + }); + + return hash.hash; + } catch (error) { + throw Error(`Failed to approve: ${error}`); + } } export async function transferFrom( - walletClient: EVMWalletClient, - token: ChainSpecificToken, - parameters: z.infer, + walletClient: EVMWalletClient, + token: ChainSpecificToken, + parameters: z.infer, ): Promise { - try { - const resolvedFromAddress = await walletClient.resolveAddress( - parameters.from, - ); - - const resolvedToAddress = await walletClient.resolveAddress(parameters.to); - - const amountInBaseUnits = parseUnits(parameters.amount, token.decimals); - - const hash = await walletClient.sendTransaction({ - to: token.contractAddress, - abi: ERC20_ABI, - functionName: "transferFrom", - args: [resolvedFromAddress, resolvedToAddress, amountInBaseUnits], - }); - - return hash.hash; - } catch (error) { - throw Error(`Failed to transfer from: ${error}`); - } + try { + const resolvedFromAddress = await walletClient.resolveAddress(parameters.from); + + const resolvedToAddress = await walletClient.resolveAddress(parameters.to); + + const amountInBaseUnits = parseUnits(parameters.amount, token.decimals); + + const hash = await walletClient.sendTransaction({ + to: token.contractAddress, + abi: ERC20_ABI, + functionName: "transferFrom", + args: [resolvedFromAddress, resolvedToAddress, amountInBaseUnits], + }); + + return hash.hash; + } catch (error) { + throw Error(`Failed to transfer from: ${error}`); + } } diff --git a/typescript/packages/plugins/erc20/src/parameters.ts b/typescript/packages/plugins/erc20/src/parameters.ts index 0a312c1e6..27074daac 100644 --- a/typescript/packages/plugins/erc20/src/parameters.ts +++ b/typescript/packages/plugins/erc20/src/parameters.ts @@ -1,28 +1,28 @@ import { z } from "zod"; export const getBalanceParametersSchema = z.object({ - wallet: z.string().describe("The address to get the balance of"), + wallet: z.string().describe("The address to get the balance of"), }); export const transferParametersSchema = z.object({ - to: z.string().describe("The address to transfer the token to"), - amount: z.string().describe("The amount of tokens to transfer"), + to: z.string().describe("The address to transfer the token to"), + amount: z.string().describe("The amount of tokens to transfer"), }); export const totalSupplyParametersSchema = z.object({}); export const allowanceParametersSchema = z.object({ - owner: z.string().describe("The address to check the allowance of"), - spender: z.string().describe("The address to check the allowance for"), + owner: z.string().describe("The address to check the allowance of"), + spender: z.string().describe("The address to check the allowance for"), }); export const approveParametersSchema = z.object({ - spender: z.string().describe("The address to approve the allowance to"), - amount: z.string().describe("The amount of tokens to approve"), + spender: z.string().describe("The address to approve the allowance to"), + amount: z.string().describe("The amount of tokens to approve"), }); export const transferFromParametersSchema = z.object({ - from: z.string().describe("The address to transfer the token from"), - to: z.string().describe("The address to transfer the token to"), - amount: z.string().describe("The amount of tokens to transfer"), + from: z.string().describe("The address to transfer the token from"), + to: z.string().describe("The address to transfer the token to"), + amount: z.string().describe("The amount of tokens to transfer"), }); diff --git a/typescript/packages/plugins/erc20/src/token.ts b/typescript/packages/plugins/erc20/src/token.ts index 558c6e375..4408146ac 100644 --- a/typescript/packages/plugins/erc20/src/token.ts +++ b/typescript/packages/plugins/erc20/src/token.ts @@ -1,33 +1,33 @@ export type Token = { - decimals: number; - symbol: string; - name: string; - chains: Record; + decimals: number; + symbol: string; + name: string; + chains: Record; }; export type ChainSpecificToken = { - chainId: number; - decimals: number; - symbol: string; - name: string; - contractAddress: `0x${string}`; + chainId: number; + decimals: number; + symbol: string; + name: string; + contractAddress: `0x${string}`; }; export const PEPE: Token = { - decimals: 18, - symbol: "PEPE", - name: "Pepe", - chains: { - "1": { - contractAddress: "0x6982508145454Ce325dDbE47a25d4ec3d2311933", - }, - "10": { - contractAddress: "0xc1c167cc44f7923cd0062c4370df962f9ddb16f5", - }, - "8453": { - contractAddress: "0xb4fde59a779991bfb6a52253b51947828b982be3", - }, - }, + decimals: 18, + symbol: "PEPE", + name: "Pepe", + chains: { + "1": { + contractAddress: "0x6982508145454Ce325dDbE47a25d4ec3d2311933", + }, + "10": { + contractAddress: "0xc1c167cc44f7923cd0062c4370df962f9ddb16f5", + }, + "8453": { + contractAddress: "0xb4fde59a779991bfb6a52253b51947828b982be3", + }, + }, }; export const USDC: Token = { @@ -56,24 +56,21 @@ export const USDC: Token = { }, }; -export function getTokensForNetwork( - chainId: number, - tokens: Token[], -): ChainSpecificToken[] { - const result: ChainSpecificToken[] = []; +export function getTokensForNetwork(chainId: number, tokens: Token[]): ChainSpecificToken[] { + const result: ChainSpecificToken[] = []; - for (const token of tokens) { - const chainData = token.chains[chainId]; - if (chainData) { - result.push({ - chainId: chainId, - decimals: token.decimals, - symbol: token.symbol, - name: token.name, - contractAddress: chainData.contractAddress, - }); - } - } + for (const token of tokens) { + const chainData = token.chains[chainId]; + if (chainData) { + result.push({ + chainId: chainId, + decimals: token.decimals, + symbol: token.symbol, + name: token.name, + contractAddress: chainData.contractAddress, + }); + } + } - return result; + return result; } diff --git a/typescript/packages/plugins/erc20/src/tools.ts b/typescript/packages/plugins/erc20/src/tools.ts index 0f573172b..f8e06df9d 100644 --- a/typescript/packages/plugins/erc20/src/tools.ts +++ b/typescript/packages/plugins/erc20/src/tools.ts @@ -1,27 +1,18 @@ -import { - allowance, - approve, - balanceOf, - totalSupply, - transfer, - transferFrom, -} from "./methods"; +import { allowance, approve, balanceOf, totalSupply, transfer, transferFrom } from "./methods"; import { allowanceParametersSchema, approveParametersSchema, - getBalanceParametersSchema, - totalSupplyParametersSchema, - transferFromParametersSchema, - transferParametersSchema, + getBalanceParametersSchema, + totalSupplyParametersSchema, + transferFromParametersSchema, + transferParametersSchema, } from "./parameters"; import type { DeferredTool, EVMWalletClient } from "@goat-sdk/core"; import type { z } from "zod"; import type { ChainSpecificToken } from "./token"; -export function getTools( - tokenList: ChainSpecificToken[] -): DeferredTool[] { +export function getTools(tokenList: ChainSpecificToken[]): DeferredTool[] { const tools: DeferredTool[] = []; for (const token of tokenList) { @@ -29,70 +20,51 @@ export function getTools( name: `get_${token.symbol}_balance`, description: `This {{tool}} gets the balance of ${token.symbol}`, parameters: getBalanceParametersSchema, - method: ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => balanceOf(walletClient, token, parameters), + method: (walletClient: EVMWalletClient, parameters: z.infer) => + balanceOf(walletClient, token, parameters), }; const transferTool: DeferredTool = { name: `transfer_${token.symbol}`, description: `This {{tool}} transfers ${token.symbol} to the specified address`, parameters: transferParametersSchema, - method: ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => transfer(walletClient, token, parameters), + method: (walletClient: EVMWalletClient, parameters: z.infer) => + transfer(walletClient, token, parameters), }; const totalSupplyTool: DeferredTool = { name: `get_${token.symbol}_total_supply`, description: `This {{tool}} gets the total supply of ${token.symbol}`, parameters: totalSupplyParametersSchema, - method: ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => totalSupply(walletClient, token), + method: (walletClient: EVMWalletClient, parameters: z.infer) => + totalSupply(walletClient, token), }; const allowanceTool: DeferredTool = { name: `get_${token.symbol}_allowance`, description: `This {{tool}} gets the allowance of ${token.symbol}`, parameters: allowanceParametersSchema, - method: ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => allowance(walletClient, token, parameters), + method: (walletClient: EVMWalletClient, parameters: z.infer) => + allowance(walletClient, token, parameters), }; const approveTool: DeferredTool = { name: `approve_${token.symbol}`, description: `This {{tool}} approves the allowance of ${token.symbol}`, parameters: approveParametersSchema, - method: ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => approve(walletClient, token, parameters), + method: (walletClient: EVMWalletClient, parameters: z.infer) => + approve(walletClient, token, parameters), }; const transferFromTool: DeferredTool = { name: `transfer_${token.symbol}_from`, description: `This {{tool}} transfers ${token.symbol} from the specified address`, parameters: transferFromParametersSchema, - method: ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => transferFrom(walletClient, token, parameters), + method: (walletClient: EVMWalletClient, parameters: z.infer) => + transferFrom(walletClient, token, parameters), }; - tools.push( - balanceTool, - transferTool, - totalSupplyTool, - allowanceTool, - approveTool, - transferFromTool - ); + tools.push(balanceTool, transferTool, totalSupplyTool, allowanceTool, approveTool, transferFromTool); } return tools; diff --git a/typescript/packages/plugins/erc20/tsconfig.json b/typescript/packages/plugins/erc20/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/plugins/erc20/tsconfig.json +++ b/typescript/packages/plugins/erc20/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/plugins/erc20/tsup.config.ts b/typescript/packages/plugins/erc20/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/plugins/erc20/tsup.config.ts +++ b/typescript/packages/plugins/erc20/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/plugins/erc20/turbo.json b/typescript/packages/plugins/erc20/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/plugins/erc20/turbo.json +++ b/typescript/packages/plugins/erc20/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/plugins/polymarket/package.json b/typescript/packages/plugins/polymarket/package.json index 342033f3d..b98964c9f 100644 --- a/typescript/packages/plugins/polymarket/package.json +++ b/typescript/packages/plugins/polymarket/package.json @@ -1,57 +1,34 @@ { - "name": "@goat-sdk/plugin-polymarket", - "version": "0.2.0", - "files": [ - "dist/**/*", - "README.md", - "package.json" - ], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "sideEffects": false, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "crypto": "^1.0.1", - "viem": "^2.21.49", - "zod": "^3.23.8" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*", - "viem": "^2.21.49" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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" - ], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/plugin-polymarket", + "version": "0.2.0", + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "sideEffects": false, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "crypto": "^1.0.1", + "viem": "^2.21.49", + "zod": "^3.23.8" + }, + "peerDependencies": { + "@goat-sdk/core": "workspace:*", + "viem": "^2.21.49" + }, + "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/polymarket/src/api.ts b/typescript/packages/plugins/polymarket/src/api.ts index 9888a2dbd..870692d06 100644 --- a/typescript/packages/plugins/polymarket/src/api.ts +++ b/typescript/packages/plugins/polymarket/src/api.ts @@ -1,35 +1,29 @@ import type { Chain, EVMWalletClient } from "@goat-sdk/core"; +import { parseUnits } from "viem"; import { polygon } from "viem/chains"; import type { z } from "zod"; +import { COLLATERAL_TOKEN_DECIMALS, CONDITIONAL_TOKEN_DECIMALS, getContractConfig } from "./contracts"; import type { + cancelOrderParametersSchema, + createOrderParametersSchema, getEventsParametersSchema, getMarketInfoParametersSchema, - createOrderParametersSchema, getOpenOrdersParametersSchema, - cancelOrderParametersSchema, } from "./parameters"; import { + ROUNDING_CONFIG, appendSearchParams, buildClobEip712Signature, buildPolyHmacSignature, getExpirationTimestamp, getOrderRawAmounts, priceValid, - ROUNDING_CONFIG, } from "./utils"; -import { - COLLATERAL_TOKEN_DECIMALS, - CONDITIONAL_TOKEN_DECIMALS, - getContractConfig, -} from "./contracts"; -import { parseUnits } from "viem"; const GAMMA_URL = "https://gamma-api.polymarket.com"; function getBaseUrl(chain: Chain): string { - return chain.id === polygon.id - ? "https://clob.polymarket.com" - : "https://clob-staging.polymarket.com"; + return chain.id === polygon.id ? "https://clob.polymarket.com" : "https://clob-staging.polymarket.com"; } export type ApiKeyCredentials = { @@ -95,13 +89,9 @@ async function getHostTimestamp(chain: Chain): Promise { async function createL1Headers( walletClient: EVMWalletClient, timestamp: number, - nonce = 0 + nonce = 0, ): Promise> { - const signature = await buildClobEip712Signature( - walletClient, - timestamp, - nonce - ); + const signature = await buildClobEip712Signature(walletClient, timestamp, nonce); const address = walletClient.getAddress(); return { @@ -115,18 +105,12 @@ async function createL1Headers( async function createL2Headers( walletClient: EVMWalletClient, credentials: ApiKeyCredentials, - { method, requestPath, body }: L2HeadersArgs + { method, requestPath, body }: L2HeadersArgs, ) { const address = walletClient.getAddress(); const timestamp = await getHostTimestamp(walletClient.getChain()); - const sig = buildPolyHmacSignature( - credentials.secret, - timestamp, - method, - requestPath, - body - ); + const sig = buildPolyHmacSignature(credentials.secret, timestamp, method, requestPath, body); const headers = { POLY_ADDRESS: address, @@ -155,30 +139,22 @@ async function getNegativeRiskAdapter(chain: Chain, tokenId: string) { const response = await fetch(url.toString()); if (!response.ok) { - throw new Error( - `Failed to fetch negative risk: ${response.statusText}` - ); + throw new Error(`Failed to fetch negative risk: ${response.statusText}`); } const result = await response.json(); return result.neg_risk as boolean; } -export async function createOrDeriveAPIKey( - walletClient: EVMWalletClient, - nonce?: number -): Promise { +export async function createOrDeriveAPIKey(walletClient: EVMWalletClient, nonce?: number): Promise { const timestamp = await getHostTimestamp(walletClient.getChain()); const headers = await createL1Headers(walletClient, timestamp, nonce); // Try to create a new API key - let response = await fetch( - `${getBaseUrl(walletClient.getChain())}/auth/api-key`, - { - method: "POST", - headers, - } - ); + let response = await fetch(`${getBaseUrl(walletClient.getChain())}/auth/api-key`, { + method: "POST", + headers, + }); if (response.ok) { const data = await response.json(); @@ -190,18 +166,13 @@ export async function createOrDeriveAPIKey( } // If creation fails, attempt to derive the API key - response = await fetch( - `${getBaseUrl(walletClient.getChain())}/auth/derive-api-key`, - { - method: "GET", - headers, - } - ); + response = await fetch(`${getBaseUrl(walletClient.getChain())}/auth/derive-api-key`, { + method: "GET", + headers, + }); if (!response.ok) { - throw new Error( - `Failed to create or derive API key: ${response.statusText}` - ); + throw new Error(`Failed to create or derive API key: ${response.statusText}`); } const data = await response.json(); @@ -213,7 +184,7 @@ export async function createOrDeriveAPIKey( } export async function getEvents( - parameters: z.infer + parameters: z.infer, // biome-ignore lint/suspicious/noExplicitAny: Need to create a schema for the response ): Promise { const url = new URL(`${GAMMA_URL}/events`); @@ -229,7 +200,7 @@ export async function getEvents( export async function getMarketInfo( walletClient: EVMWalletClient, - parameters: z.infer + parameters: z.infer, ) { const chain = walletClient.getChain(); const url = new URL(`${getBaseUrl(chain)}/markets/${parameters.id}`); @@ -246,25 +217,20 @@ export async function getMarketInfo( export async function createOrder( walletClient: EVMWalletClient, credentials: ApiKeyCredentials, - parameters: z.infer + parameters: z.infer, ) { const chain = walletClient.getChain(); const tokenId = parameters.tokenId; const price = parameters.price; const orderType = parameters.type as OrderType; - const expiration = - orderType === OrderType.GTD - ? getExpirationTimestamp(parameters.expiration).toString() - : "0"; + const expiration = orderType === OrderType.GTD ? getExpirationTimestamp(parameters.expiration).toString() : "0"; const size = parameters.size; const side = parameters.side as Side; const fees = "0"; const tickSize = await getTickSize(chain, tokenId); if (!priceValid(Number(price), tickSize)) { - throw new Error( - `Invalid price (${price}), min: ${tickSize} - max: ${1 - tickSize}` - ); + throw new Error(`Invalid price (${price}), min: ${tickSize} - max: ${1 - tickSize}`); } const usesNegRiskAdapter = await getNegativeRiskAdapter(chain, tokenId); @@ -275,21 +241,10 @@ export async function createOrder( side: intSide, rawMakerAmt, rawTakerAmt, - } = getOrderRawAmounts( - side, - Number(size), - Number(price), - ROUNDING_CONFIG[tickSize as TickSize] - ); - - const makerAmount = parseUnits( - rawMakerAmt.toString(), - COLLATERAL_TOKEN_DECIMALS - ).toString(); - const takerAmount = parseUnits( - rawTakerAmt.toString(), - CONDITIONAL_TOKEN_DECIMALS - ).toString(); + } = getOrderRawAmounts(side, Number(size), Number(price), ROUNDING_CONFIG[tickSize as TickSize]); + + const makerAmount = parseUnits(rawMakerAmt.toString(), COLLATERAL_TOKEN_DECIMALS).toString(); + const takerAmount = parseUnits(rawTakerAmt.toString(), CONDITIONAL_TOKEN_DECIMALS).toString(); // Make order public to everyone const taker = "0x0000000000000000000000000000000000000000"; @@ -352,13 +307,7 @@ export async function createOrder( // Submit order const timestamp = await getHostTimestamp(chain); - const sig = buildPolyHmacSignature( - credentials.secret, - timestamp, - "POST", - "/order", - JSON.stringify(payload) - ); + const sig = buildPolyHmacSignature(credentials.secret, timestamp, "POST", "/order", JSON.stringify(payload)); const headers = { POLY_ADDRESS: walletClient.getAddress(), @@ -375,9 +324,7 @@ export async function createOrder( }); if (!response.ok) { - throw new Error( - `Failed to create order: ${JSON.stringify(await response.json())}` - ); + throw new Error(`Failed to create order: ${JSON.stringify(await response.json())}`); } return await response.json(); @@ -386,7 +333,7 @@ export async function createOrder( export async function getOpenOrders( walletClient: EVMWalletClient, credentials: ApiKeyCredentials, - parameters: z.infer + parameters: z.infer, ) { const url = new URL(`${getBaseUrl(walletClient.getChain())}/data/orders`); appendSearchParams(url, parameters); @@ -411,7 +358,7 @@ export async function getOpenOrders( export async function cancelOrder( walletClient: EVMWalletClient, credentials: ApiKeyCredentials, - parameters: z.infer + parameters: z.infer, ) { const body = { orderID: parameters.id }; const headers = await createL2Headers(walletClient, credentials, { @@ -420,14 +367,11 @@ export async function cancelOrder( body: JSON.stringify(body), }); - const response = await fetch( - `${getBaseUrl(walletClient.getChain())}/order`, - { - method: "DELETE", - headers, - body: JSON.stringify(body), - } - ); + const response = await fetch(`${getBaseUrl(walletClient.getChain())}/order`, { + method: "DELETE", + headers, + body: JSON.stringify(body), + }); if (!response.ok) { throw new Error(`Failed to cancel order: ${response.statusText}`); @@ -436,22 +380,16 @@ export async function cancelOrder( return await response.json(); } -export async function cancelAllOrders( - walletClient: EVMWalletClient, - credentials: ApiKeyCredentials -) { +export async function cancelAllOrders(walletClient: EVMWalletClient, credentials: ApiKeyCredentials) { const headers = await createL2Headers(walletClient, credentials, { method: "DELETE", requestPath: "/cancel-all", }); - const response = await fetch( - `${getBaseUrl(walletClient.getChain())}/cancel-all`, - { - method: "DELETE", - headers, - } - ); + const response = await fetch(`${getBaseUrl(walletClient.getChain())}/cancel-all`, { + method: "DELETE", + headers, + }); if (!response.ok) { throw new Error(`Failed to cancel all orders: ${response.statusText}`); diff --git a/typescript/packages/plugins/polymarket/src/contracts.ts b/typescript/packages/plugins/polymarket/src/contracts.ts index 9597c499b..52e6bf2fb 100644 --- a/typescript/packages/plugins/polymarket/src/contracts.ts +++ b/typescript/packages/plugins/polymarket/src/contracts.ts @@ -27,10 +27,7 @@ const MATIC_CONTRACTS: ContractConfig = { conditionalTokens: "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045", }; -export function getContractConfig( - chain: Chain, - usesNegRiskAdapter: boolean -): string { +export function getContractConfig(chain: Chain, usesNegRiskAdapter: boolean): string { if (chain.id === 137) { if (usesNegRiskAdapter) { return MATIC_CONTRACTS.negRiskExchange; diff --git a/typescript/packages/plugins/polymarket/src/index.ts b/typescript/packages/plugins/polymarket/src/index.ts index c6f8c5b50..4d86720b0 100644 --- a/typescript/packages/plugins/polymarket/src/index.ts +++ b/typescript/packages/plugins/polymarket/src/index.ts @@ -1,19 +1,16 @@ import type { Chain, EVMWalletClient, Plugin } from "@goat-sdk/core"; -import { getTools } from "./tools"; import { polygon } from "viem/chains"; -import { type ApiKeyCredentials, createOrder, createOrDeriveAPIKey } from "./api"; +import { type ApiKeyCredentials, createOrDeriveAPIKey, createOrder } from "./api"; +import { getTools } from "./tools"; export type PolymarketOptions = { credentials: ApiKeyCredentials; }; -export function polymarket({ - credentials, -}: PolymarketOptions): Plugin { +export function polymarket({ credentials }: PolymarketOptions): Plugin { return { name: "Polymarket", - supportsChain: (chain: Chain) => - chain.type === "evm" && chain.id === polygon.id, + supportsChain: (chain: Chain) => chain.type === "evm" && chain.id === polygon.id, supportsSmartWallets: () => false, getTools: async () => { return getTools({ diff --git a/typescript/packages/plugins/polymarket/src/parameters.ts b/typescript/packages/plugins/polymarket/src/parameters.ts index 80c2da0e9..e4f26bf18 100644 --- a/typescript/packages/plugins/polymarket/src/parameters.ts +++ b/typescript/packages/plugins/polymarket/src/parameters.ts @@ -3,44 +3,19 @@ import { z } from "zod"; export const getEventsParametersSchema = z.object({ id: z.optional(z.string()).describe("The id of the event to get"), slug: z.optional(z.string()).describe("The slug of the event to get"), - archived: z - .optional(z.boolean()) - .describe("Whether to get archived events or not"), - closed: z - .optional(z.boolean()) - .describe("Whether to get closed events or not"), - startDateMin: z - .optional(z.string()) - .describe("The minimum start date of the events to get"), - startDateMax: z - .optional(z.string()) - .describe("The maximum start date of the events to get"), - endDateMin: z - .optional(z.string()) - .describe("The minimum end date of the events to get"), - endDateMax: z - .optional(z.string()) - .describe("The maximum end date of the events to get"), - ascending: z - .optional(z.boolean()) - .describe("Whether to get the events in ascending order or not"), + archived: z.optional(z.boolean()).describe("Whether to get archived events or not"), + closed: z.optional(z.boolean()).describe("Whether to get closed events or not"), + startDateMin: z.optional(z.string()).describe("The minimum start date of the events to get"), + startDateMax: z.optional(z.string()).describe("The maximum start date of the events to get"), + endDateMin: z.optional(z.string()).describe("The minimum end date of the events to get"), + endDateMax: z.optional(z.string()).describe("The maximum end date of the events to get"), + ascending: z.optional(z.boolean()).describe("Whether to get the events in ascending order or not"), order: z - .optional( - z.enum([ - "start_date_min", - "start_date_max", - "end_date_min", - "end_date_max", - ]) - ) + .optional(z.enum(["start_date_min", "start_date_max", "end_date_min", "end_date_max"])) .describe("The field to order the events by"), - limit: z - .optional(z.number()) - .describe("The maximum number of events to get"), + limit: z.optional(z.number()).describe("The maximum number of events to get"), offset: z.optional(z.number()).describe("The number of events to skip"), - liquidityMin: z - .optional(z.number()) - .describe("The minimum liquidity of the events to get"), + liquidityMin: z.optional(z.number()).describe("The minimum liquidity of the events to get"), }); export const getMarketInfoParametersSchema = z.object({ @@ -54,16 +29,12 @@ export const createOrderParametersSchema = z.object({ "The type of the order:\n" + "- `FOK`: A 'Fill-Or-Kill' order is a market order to buy shares that must be executed immediately in its entirety; otherwise, the entire order will be cancelled.\n" + "- `GTC`: A 'Good-Til-Cancelled' order is a limit order that is active until it is fulfilled or cancelled.\n" + - "- `GTD`: A 'Good-Til-Day' order is active until its specified expiration date (provided as a UTC seconds timestamp)." + "- `GTD`: A 'Good-Til-Day' order is active until its specified expiration date (provided as a UTC seconds timestamp).", ), - tokenId: z - .string() - .describe("ERC1155 token ID of the conditional token being traded"), + tokenId: z.string().describe("ERC1155 token ID of the conditional token being traded"), price: z.string().describe("Price of the conditional token being traded"), size: z.number().describe("How many shares to buy or sell"), - expiration: z - .number() - .describe("Time in seconds until the order expires"), + expiration: z.number().describe("Time in seconds until the order expires"), side: z.enum(["BUY", "SELL"]).describe("Buy or sell"), }); @@ -77,4 +48,4 @@ export const cancelOrderParametersSchema = z.object({ id: z.string().describe("The id of the order to cancel"), }); -export const cancelAllOrdersParametersSchema = z.object({}); \ No newline at end of file +export const cancelAllOrdersParametersSchema = z.object({}); diff --git a/typescript/packages/plugins/polymarket/src/tools.ts b/typescript/packages/plugins/polymarket/src/tools.ts index 9fb939fa5..b9882c892 100644 --- a/typescript/packages/plugins/polymarket/src/tools.ts +++ b/typescript/packages/plugins/polymarket/src/tools.ts @@ -3,51 +3,37 @@ import type { z } from "zod"; import type { ApiKeyCredentials } from "./api"; import { + cancelAllOrdersParametersSchema, + cancelOrderParametersSchema, createOrderParametersSchema, getEventsParametersSchema, getMarketInfoParametersSchema, getOpenOrdersParametersSchema, - cancelOrderParametersSchema, - cancelAllOrdersParametersSchema, } from "./parameters"; -import { - createOrder, - getEvents, - getMarketInfo, - getOpenOrders, - cancelOrder, - cancelAllOrders, -} from "./api"; +import { cancelAllOrders, cancelOrder, createOrder, getEvents, getMarketInfo, getOpenOrders } from "./api"; export type PolymarketToolsOptions = { credentials: ApiKeyCredentials; }; -export function getTools({ - credentials, -}: PolymarketToolsOptions): DeferredTool[] { +export function getTools({ credentials }: PolymarketToolsOptions): DeferredTool[] { return [ { name: "get_polymarket_events", - description: - "This {{tool}} gets the events on Polymarket including their markets", + description: "This {{tool}} gets the events on Polymarket including their markets", parameters: getEventsParametersSchema, - method: async ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => { + method: async (walletClient: EVMWalletClient, parameters: z.infer) => { return getEvents(parameters); }, }, { name: "get_polymarket_market_info", - description: - "This {{tool}} gets the info of a specific market on Polymarket", + description: "This {{tool}} gets the info of a specific market on Polymarket", parameters: getMarketInfoParametersSchema, method: async ( walletClient: EVMWalletClient, - parameters: z.infer + parameters: z.infer, ) => { return getMarketInfo(walletClient, parameters); }, @@ -56,10 +42,7 @@ export function getTools({ name: "create_order_on_polymarket", description: "This {{tool}} creates an order on Polymarket", parameters: createOrderParametersSchema, - method: async ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => { + method: async (walletClient: EVMWalletClient, parameters: z.infer) => { return createOrder(walletClient, credentials, parameters); }, }, @@ -69,7 +52,7 @@ export function getTools({ parameters: getOpenOrdersParametersSchema, method: async ( walletClient: EVMWalletClient, - parameters: z.infer + parameters: z.infer, ) => { return getOpenOrders(walletClient, credentials, parameters); }, @@ -78,10 +61,7 @@ export function getTools({ name: "cancel_polymarket_order", description: "This {{tool}} cancels an order on Polymarket", parameters: cancelOrderParametersSchema, - method: async ( - walletClient: EVMWalletClient, - parameters: z.infer - ) => { + method: async (walletClient: EVMWalletClient, parameters: z.infer) => { return cancelOrder(walletClient, credentials, parameters); }, }, @@ -91,7 +71,7 @@ export function getTools({ parameters: cancelAllOrdersParametersSchema, method: async ( walletClient: EVMWalletClient, - parameters: z.infer + parameters: z.infer, ) => { return cancelAllOrders(walletClient, credentials); }, diff --git a/typescript/packages/plugins/polymarket/src/utils.ts b/typescript/packages/plugins/polymarket/src/utils.ts index 7217afe36..46950342f 100644 --- a/typescript/packages/plugins/polymarket/src/utils.ts +++ b/typescript/packages/plugins/polymarket/src/utils.ts @@ -1,6 +1,6 @@ +import crypto from "node:crypto"; import type { EVMWalletClient } from "@goat-sdk/core"; import { polygon } from "viem/chains"; -import crypto from "node:crypto"; import { IntSide, Side, type TickSize } from "./api"; export function camelToSnake(str: string): string { @@ -12,7 +12,7 @@ export function buildPolyHmacSignature( timestamp: number, method: string, requestPath: string, - body?: string + body?: string, ): string { const message = `${timestamp}${method}${requestPath}${body ?? ""}`; const base64Secret = Buffer.from(secret, "base64"); @@ -28,7 +28,7 @@ const MSG_TO_SIGN = "This message attests that I control the given wallet"; export async function buildClobEip712Signature( walletClient: EVMWalletClient, timestamp: number, - nonce: number + nonce: number, ): Promise { const address = walletClient.getAddress(); const domain = { @@ -65,10 +65,7 @@ export async function buildClobEip712Signature( export function appendSearchParams( url: URL, - parameters: Record< - string, - string | number | boolean | (string | number | boolean)[] - > + parameters: Record, ) { for (const [key, value] of Object.entries(parameters)) { if (value !== undefined) { @@ -121,7 +118,7 @@ export function getOrderRawAmounts( side: Side, size: number, price: number, - roundConfig: RoundConfig + roundConfig: RoundConfig, ): { side: IntSide; rawMakerAmt: number; rawTakerAmt: number } { const rawPrice = roundNormal(price, roundConfig.price); @@ -165,21 +162,21 @@ export function roundNormal(num: number, decimals: number) { return num; } return Math.round((num + Number.EPSILON) * 10 ** decimals) / 10 ** decimals; -}; +} export function roundDown(num: number, decimals: number) { if (decimalPlaces(num) <= decimals) { return num; } return Math.floor(num * 10 ** decimals) / 10 ** decimals; -}; +} export function roundUp(num: number, decimals: number) { if (decimalPlaces(num) <= decimals) { return num; } return Math.ceil(num * 10 ** decimals) / 10 ** decimals; -}; +} export function decimalPlaces(num: number) { if (Number.isInteger(num)) { @@ -192,7 +189,7 @@ export function decimalPlaces(num: number) { } return arr[1].length; -}; +} export function getExpirationTimestamp(secondsToAdd: number) { const currentUnixTimestamp = Math.floor(Date.now() / 1000); diff --git a/typescript/packages/plugins/polymarket/tsconfig.json b/typescript/packages/plugins/polymarket/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/plugins/polymarket/tsconfig.json +++ b/typescript/packages/plugins/polymarket/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/plugins/polymarket/tsup.config.ts b/typescript/packages/plugins/polymarket/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/plugins/polymarket/tsup.config.ts +++ b/typescript/packages/plugins/polymarket/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/plugins/polymarket/turbo.json b/typescript/packages/plugins/polymarket/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/plugins/polymarket/turbo.json +++ b/typescript/packages/plugins/polymarket/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/wallets/crossmint/README.md b/typescript/packages/wallets/crossmint/README.md index bbc0c0582..ed6591808 100644 --- a/typescript/packages/wallets/crossmint/README.md +++ b/typescript/packages/wallets/crossmint/README.md @@ -95,6 +95,6 @@ const { faucet } = crossmint(apiKey); const tools = await getOnChainTools({ wallet: viem(walletClient), - faucet: faucet(), + plugins: [faucet()], }); -``` \ No newline at end of file +``` diff --git a/typescript/packages/wallets/crossmint/package.json b/typescript/packages/wallets/crossmint/package.json index b2a48e0f6..0c35e7619 100644 --- a/typescript/packages/wallets/crossmint/package.json +++ b/typescript/packages/wallets/crossmint/package.json @@ -1,50 +1,35 @@ { - "name": "@goat-sdk/crossmint", - "version": "0.1.5", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "@solana/web3.js": "1.95.8", - "abitype": "^1.0.6", - "bs58": "^6.0.0", - "viem": "^2.21.49", - "zod": "^3.23.8" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/crossmint", + "version": "0.1.5", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "@solana/web3.js": "1.95.8", + "abitype": "^1.0.6", + "bs58": "^6.0.0", + "viem": "^2.21.49", + "zod": "^3.23.8" + }, + "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/wallets/crossmint/src/api.ts b/typescript/packages/wallets/crossmint/src/api.ts index f762b5dc5..8b64f1d62 100644 --- a/typescript/packages/wallets/crossmint/src/api.ts +++ b/typescript/packages/wallets/crossmint/src/api.ts @@ -2,38 +2,38 @@ import type { EVMTypedData } from "@goat-sdk/core"; import type { SupportedSmartWalletChains } from "./chains"; type CoreSignerType = - | "evm-keypair" - | "solana-keypair" - | "webauthn" - | "evm-fireblocks-custodial" - | "solana-fireblocks-custodial" - | "evm-keypair-session"; + | "evm-keypair" + | "solana-keypair" + | "webauthn" + | "evm-fireblocks-custodial" + | "solana-fireblocks-custodial" + | "evm-keypair-session"; type AdminSigner = { - type: CoreSignerType; - address?: string; - locator?: string; + type: CoreSignerType; + address?: string; + locator?: string; }; //////////////////////////////////////////////////////////////////// // Create Wallet //////////////////////////////////////////////////////////////////// interface CreateWalletRequest { - type: "evm-smart-wallet" | "solana-custodial-wallet"; - config?: { - adminSigner?: AdminSigner; - }; - linkedUser?: string; + type: "evm-smart-wallet" | "solana-custodial-wallet"; + config?: { + adminSigner?: AdminSigner; + }; + linkedUser?: string; } interface CreateWalletResponse { - type: "evm-smart-wallet" | "solana-custodial-wallet"; - address: string; - config: { - adminSigner?: AdminSigner; - }; - linkedUser?: string; - createdAt: string; + type: "evm-smart-wallet" | "solana-custodial-wallet"; + address: string; + config: { + adminSigner?: AdminSigner; + }; + linkedUser?: string; + createdAt: string; } //////////////////////////////////////////////////////////////////// @@ -45,55 +45,55 @@ interface GetWalletResponse extends CreateWalletResponse {} // Create Transaction //////////////////////////////////////////////////////////////////// interface TransactionApprovals { - pending: Omit[]; - submitted: ApprovalSubmission[]; - required?: number; // For multisig scenarios, tentative until we support + pending: Omit[]; + submitted: ApprovalSubmission[]; + required?: number; // For multisig scenarios, tentative until we support } interface ApprovalSubmission { - signer: string; // signing locator {type}:{id} - message: string; - submittedAt: string; // timestamp - signature: string; - metadata?: object; // additional data, user agent, etc + signer: string; // signing locator {type}:{id} + message: string; + submittedAt: string; // timestamp + signature: string; + metadata?: object; // additional data, user agent, etc } interface CreateTransactionRequest { - params: TransactionParams; + params: TransactionParams; } interface CreateTransactionResponse { - id: string; - walletType: "evm-smart-wallet" | "solana-custodial-wallet"; - status: "awaiting-approval" | "pending" | "failed" | "success"; - approvals?: TransactionApprovals; - params: TransactionParams; - onChain?: { - userOperation?: object; - userOperationHash?: string; - chain?: string; - txId?: string; - }; - createdAt: string; + id: string; + walletType: "evm-smart-wallet" | "solana-custodial-wallet"; + status: "awaiting-approval" | "pending" | "failed" | "success"; + approvals?: TransactionApprovals; + params: TransactionParams; + onChain?: { + userOperation?: object; + userOperationHash?: string; + chain?: string; + txId?: string; + }; + createdAt: string; } interface Approval { - signer: string; - signature: string; + signer: string; + signature: string; } interface TransactionParams { - calls?: Call[]; - chain?: string; - signer?: string; - transaction?: string; - signers?: string[]; + calls?: Call[]; + chain?: string; + signer?: string; + transaction?: string; + signers?: string[]; } interface Call { - to: string; - value: string; - data: string; + to: string; + value: string; + data: string; } //////////////////////////////////////////////////////////////////// @@ -105,10 +105,10 @@ interface TransactionStatusResponse extends CreateTransactionResponse {} // Submit Approval //////////////////////////////////////////////////////////////////// interface SubmitApprovalRequest { - approvals: { - signer: string; - signature: string; - }[]; + approvals: { + signer: string; + signature: string; + }[]; } interface SubmitApprovalResponse extends CreateTransactionResponse {} @@ -117,65 +117,65 @@ interface SubmitApprovalResponse extends CreateTransactionResponse {} // Sign Message //////////////////////////////////////////////////////////////////// interface SignMessageRequest { - type: "evm-message" | "solana-message"; - params: { - message: string; - signer?: string; - chain?: string; - }; + type: "evm-message" | "solana-message"; + params: { + message: string; + signer?: string; + chain?: string; + }; } interface SignMessageResponse { - id: string; - walletType: "evm-smart-wallet" | "solana-custodial-wallet"; - status: string; - outputSignature: string; - approvals: TransactionApprovals; - createdAt: string; + id: string; + walletType: "evm-smart-wallet" | "solana-custodial-wallet"; + status: string; + outputSignature: string; + approvals: TransactionApprovals; + createdAt: string; } //////////////////////////////////////////////////////////////////// // Sign Typed Data //////////////////////////////////////////////////////////////////// interface SignTypedDataRequest { - type: "evm-typed-data"; - params: { - typedData: EVMTypedData; - chain?: string; - signer: string; - }; + type: "evm-typed-data"; + params: { + typedData: EVMTypedData; + chain?: string; + signer: string; + }; } interface SignTypedDataResponse { - id: string; - type: "evm-typed-data"; - params: { - typedData: EVMTypedData; - chain?: string; - signer: string; - }; - status: string; - createdAt: string; - approvals: TransactionApprovals; + id: string; + type: "evm-typed-data"; + params: { + typedData: EVMTypedData; + chain?: string; + signer: string; + }; + status: string; + createdAt: string; + approvals: TransactionApprovals; } //////////////////////////////////////////////////////////////////// // Approve Signature //////////////////////////////////////////////////////////////////// interface ApproveSignatureRequest { - approvals: { - signer: string; - signature: string; - }[]; + approvals: { + signer: string; + signature: string; + }[]; } interface ApproveSignatureResponse { - id: string; - walletType: "evm-smart-wallet" | "solana-custodial-wallet"; - status: string; - outputSignature?: string; - approvals: TransactionApprovals; - createdAt: string; + id: string; + walletType: "evm-smart-wallet" | "solana-custodial-wallet"; + status: string; + outputSignature?: string; + approvals: TransactionApprovals; + createdAt: string; } //////////////////////////////////////////////////////////////////// @@ -183,261 +183,234 @@ interface ApproveSignatureResponse { //////////////////////////////////////////////////////////////////// type APIResponse = - | CreateWalletResponse - | CreateTransactionResponse - | GetWalletResponse - | SubmitApprovalResponse - | SignMessageResponse - | SignTypedDataResponse - | ApproveSignatureResponse; - -export function createCrossmintAPI( - apiKey: string, - env: "staging" | "production", -) { - const baseUrl = - env === "staging" - ? "https://staging.crossmint.com/api/v1-alpha2" - : "https://wwww.crossmint.com/api/v1-alpha2"; - - /** - * Makes an HTTP request to the Crossmint API. - * - * @param endpoint - The API endpoint (relative to baseUrl). - * @param options - Fetch options including method, headers, and body. - * @returns The parsed JSON response. - * @throws An error if the response is not OK. - */ - const request = async ( - endpoint: string, - options: RequestInit = {}, - ): Promise => { - const url = `${baseUrl}${endpoint}`; - - // Set default headers and merge with any additional headers - const headers = new Headers({ - "X-API-KEY": apiKey, - "Content-Type": "application/json", - ...(options.headers || {}), - }); - - const response = await fetch(url, { ...options, headers }); - - let responseBody: APIResponse; - - responseBody = await response.json(); - - if (!response.ok) { - throw new Error( - `Error ${response.status}: ${JSON.stringify(responseBody)}`, - ); - } - - return responseBody; - }; - - return { - createSmartWallet: async ( - adminSigner?: AdminSigner, - ): Promise => { - const endpoint = "/wallets"; - const payload = { - type: "evm-smart-wallet", - config: { - adminSigner: adminSigner, - }, - } as CreateWalletRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as CreateWalletResponse; - }, - createCustodialWallet: async ( - linkedUser: string, - ): Promise => { - const endpoint = "/wallets"; - const payload = { - type: "solana-custodial-wallet", - linkedUser: linkedUser, - } as CreateWalletRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as CreateWalletResponse; - }, - getWallet: async (locator: string): Promise => { - const endpoint = `/wallets/${encodeURIComponent(locator)}`; - return (await request(endpoint, { - method: "GET", - })) as GetWalletResponse; - }, - signMessageForCustodialWallet: async ( - locator: string, - message: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent(locator)}/signatures`; - - const payload = { - type: "solana-message", - params: { - message: message, - }, - } as SignMessageRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as SignMessageResponse; - }, - signMessageForSmartWallet: async ( - walletAddress: string, - message: string, - chain: SupportedSmartWalletChains, - signer?: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent( - walletAddress, - )}/signatures`; - - const payload = { - type: "evm-message", - params: { - message: message, - signer: signer, - chain: chain, - }, - } as SignMessageRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as SignMessageResponse; - }, - signTypedDataForSmartWallet: async ( - walletAddress: string, - typedData: EVMTypedData, - chain: SupportedSmartWalletChains, - signer?: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent(walletAddress)}/signatures`; - - const payload = { - type: "evm-typed-data", - params: { - typedData: typedData, - chain: chain, - signer: signer, - }, - } as SignTypedDataRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as SignTypedDataResponse; - }, - checkSignatureStatus: async ( - signatureId: string, - walletAddress: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent(walletAddress)}/signatures/${encodeURIComponent(signatureId)}`; - - return (await request(endpoint, { - method: "GET", - })) as ApproveSignatureResponse; - }, - approveSignatureForSmartWallet: async ( - signatureId: string, - locator: string, - signer: string, - signature: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent( - locator, - )}/signatures/${encodeURIComponent(signatureId)}/approvals`; - - const payload = { - approvals: [ - { - signer: signer, - signature: signature, - }, - ], - } as ApproveSignatureRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as ApproveSignatureResponse; - }, - createTransactionForCustodialWallet: async ( - locator: string, - transaction: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent(locator)}/transactions`; - const payload = { - params: { - transaction: transaction, - }, - } as CreateTransactionRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as CreateTransactionResponse; - }, - createTransactionForSmartWallet: async ( - walletAddress: string, - calls: Call[], - chain: SupportedSmartWalletChains, - signer?: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent( - walletAddress, - )}/transactions`; - const payload = { - params: { - calls: calls, - chain: chain, - signer: `evm-keypair:${signer}`, - }, - } as CreateTransactionRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as CreateTransactionResponse; - }, - approveTransaction: async ( - locator: string, - transactionId: string, - approvals: Approval[], - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent( - locator, - )}/transactions/${encodeURIComponent(transactionId)}/approvals`; - - const payload = { - approvals: approvals, - } as SubmitApprovalRequest; - - return (await request(endpoint, { - method: "POST", - body: JSON.stringify(payload), - })) as SubmitApprovalResponse; - }, - checkTransactionStatus: async ( - locator: string, - transactionId: string, - ): Promise => { - const endpoint = `/wallets/${encodeURIComponent( - locator, - )}/transactions/${encodeURIComponent(transactionId)}`; - - return (await request(endpoint, { - method: "GET", - })) as TransactionStatusResponse; - }, - }; + | CreateWalletResponse + | CreateTransactionResponse + | GetWalletResponse + | SubmitApprovalResponse + | SignMessageResponse + | SignTypedDataResponse + | ApproveSignatureResponse; + +export function createCrossmintAPI(apiKey: string, env: "staging" | "production") { + const baseUrl = + env === "staging" ? "https://staging.crossmint.com/api/v1-alpha2" : "https://wwww.crossmint.com/api/v1-alpha2"; + + /** + * Makes an HTTP request to the Crossmint API. + * + * @param endpoint - The API endpoint (relative to baseUrl). + * @param options - Fetch options including method, headers, and body. + * @returns The parsed JSON response. + * @throws An error if the response is not OK. + */ + const request = async (endpoint: string, options: RequestInit = {}): Promise => { + const url = `${baseUrl}${endpoint}`; + + // Set default headers and merge with any additional headers + const headers = new Headers({ + "X-API-KEY": apiKey, + "Content-Type": "application/json", + ...(options.headers || {}), + }); + + const response = await fetch(url, { ...options, headers }); + + let responseBody: APIResponse; + + responseBody = await response.json(); + + if (!response.ok) { + throw new Error(`Error ${response.status}: ${JSON.stringify(responseBody)}`); + } + + return responseBody; + }; + + return { + createSmartWallet: async (adminSigner?: AdminSigner): Promise => { + const endpoint = "/wallets"; + const payload = { + type: "evm-smart-wallet", + config: { + adminSigner: adminSigner, + }, + } as CreateWalletRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as CreateWalletResponse; + }, + createCustodialWallet: async (linkedUser: string): Promise => { + const endpoint = "/wallets"; + const payload = { + type: "solana-custodial-wallet", + linkedUser: linkedUser, + } as CreateWalletRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as CreateWalletResponse; + }, + getWallet: async (locator: string): Promise => { + const endpoint = `/wallets/${encodeURIComponent(locator)}`; + return (await request(endpoint, { + method: "GET", + })) as GetWalletResponse; + }, + signMessageForCustodialWallet: async (locator: string, message: string): Promise => { + const endpoint = `/wallets/${encodeURIComponent(locator)}/signatures`; + + const payload = { + type: "solana-message", + params: { + message: message, + }, + } as SignMessageRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as SignMessageResponse; + }, + signMessageForSmartWallet: async ( + walletAddress: string, + message: string, + chain: SupportedSmartWalletChains, + signer?: string, + ): Promise => { + const endpoint = `/wallets/${encodeURIComponent(walletAddress)}/signatures`; + + const payload = { + type: "evm-message", + params: { + message: message, + signer: signer, + chain: chain, + }, + } as SignMessageRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as SignMessageResponse; + }, + signTypedDataForSmartWallet: async ( + walletAddress: string, + typedData: EVMTypedData, + chain: SupportedSmartWalletChains, + signer?: string, + ): Promise => { + const endpoint = `/wallets/${encodeURIComponent(walletAddress)}/signatures`; + + const payload = { + type: "evm-typed-data", + params: { + typedData: typedData, + chain: chain, + signer: signer, + }, + } as SignTypedDataRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as SignTypedDataResponse; + }, + checkSignatureStatus: async (signatureId: string, walletAddress: string): Promise => { + const endpoint = `/wallets/${encodeURIComponent(walletAddress)}/signatures/${encodeURIComponent(signatureId)}`; + + return (await request(endpoint, { + method: "GET", + })) as ApproveSignatureResponse; + }, + approveSignatureForSmartWallet: async ( + signatureId: string, + locator: string, + signer: string, + signature: string, + ): Promise => { + const endpoint = `/wallets/${encodeURIComponent( + locator, + )}/signatures/${encodeURIComponent(signatureId)}/approvals`; + + const payload = { + approvals: [ + { + signer: signer, + signature: signature, + }, + ], + } as ApproveSignatureRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as ApproveSignatureResponse; + }, + createTransactionForCustodialWallet: async ( + locator: string, + transaction: string, + ): Promise => { + const endpoint = `/wallets/${encodeURIComponent(locator)}/transactions`; + const payload = { + params: { + transaction: transaction, + }, + } as CreateTransactionRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as CreateTransactionResponse; + }, + createTransactionForSmartWallet: async ( + walletAddress: string, + calls: Call[], + chain: SupportedSmartWalletChains, + signer?: string, + ): Promise => { + const endpoint = `/wallets/${encodeURIComponent(walletAddress)}/transactions`; + const payload = { + params: { + calls: calls, + chain: chain, + signer: `evm-keypair:${signer}`, + }, + } as CreateTransactionRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as CreateTransactionResponse; + }, + approveTransaction: async ( + locator: string, + transactionId: string, + approvals: Approval[], + ): Promise => { + const endpoint = `/wallets/${encodeURIComponent( + locator, + )}/transactions/${encodeURIComponent(transactionId)}/approvals`; + + const payload = { + approvals: approvals, + } as SubmitApprovalRequest; + + return (await request(endpoint, { + method: "POST", + body: JSON.stringify(payload), + })) as SubmitApprovalResponse; + }, + checkTransactionStatus: async (locator: string, transactionId: string): Promise => { + const endpoint = `/wallets/${encodeURIComponent( + locator, + )}/transactions/${encodeURIComponent(transactionId)}`; + + return (await request(endpoint, { + method: "GET", + })) as TransactionStatusResponse; + }, + }; } diff --git a/typescript/packages/wallets/crossmint/src/chains.ts b/typescript/packages/wallets/crossmint/src/chains.ts index 68770c583..6f11fdc9e 100644 --- a/typescript/packages/wallets/crossmint/src/chains.ts +++ b/typescript/packages/wallets/crossmint/src/chains.ts @@ -1,92 +1,76 @@ import { - type Chain, - arbitrum, - arbitrumSepolia, - avalancheFuji, - base, - baseSepolia, - optimism, - optimismSepolia, - polygon, - polygonAmoy, - sepolia, - skaleNebulaTestnet, - victionTestnet, + type Chain, + arbitrum, + arbitrumSepolia, + avalancheFuji, + base, + baseSepolia, + optimism, + optimismSepolia, + polygon, + polygonAmoy, + sepolia, + skaleNebulaTestnet, + victionTestnet, } from "viem/chains"; const faucetChains = [ - "arbitrum-sepolia", - "avalanche-fuji", - "base-sepolia", - "ethereum-sepolia", - "optimism-sepolia", - "polygon-amoy", - "skale-nebula-testnet", - "viction-testnet", + "arbitrum-sepolia", + "avalanche-fuji", + "base-sepolia", + "ethereum-sepolia", + "optimism-sepolia", + "polygon-amoy", + "skale-nebula-testnet", + "viction-testnet", ] as const; type SupportedFaucetChains = (typeof faucetChains)[number]; const smartWalletChains = [ - "polygon", - "polygon-amoy", - "base", - "base-sepolia", - "arbitrum", - "arbitrum-sepolia", - "optimism", - "optimism-sepolia", + "polygon", + "polygon-amoy", + "base", + "base-sepolia", + "arbitrum", + "arbitrum-sepolia", + "optimism", + "optimism-sepolia", ] as const; export type SupportedSmartWalletChains = (typeof smartWalletChains)[number]; -const chainMap: Record< - SupportedFaucetChains | SupportedSmartWalletChains, - Chain -> = { - arbitrum: arbitrum, - "arbitrum-sepolia": arbitrumSepolia, - base: base, - "base-sepolia": baseSepolia, - optimism: optimism, - "optimism-sepolia": optimismSepolia, - polygon: polygon, - "polygon-amoy": polygonAmoy, - "avalanche-fuji": avalancheFuji, - "ethereum-sepolia": sepolia, - "skale-nebula-testnet": skaleNebulaTestnet, - "viction-testnet": victionTestnet, +const chainMap: Record = { + arbitrum: arbitrum, + "arbitrum-sepolia": arbitrumSepolia, + base: base, + "base-sepolia": baseSepolia, + optimism: optimism, + "optimism-sepolia": optimismSepolia, + polygon: polygon, + "polygon-amoy": polygonAmoy, + "avalanche-fuji": avalancheFuji, + "ethereum-sepolia": sepolia, + "skale-nebula-testnet": skaleNebulaTestnet, + "viction-testnet": victionTestnet, }; -export function getViemChain( - chain: SupportedSmartWalletChains | SupportedFaucetChains, -): Chain { - const viemChain = chainMap[chain]; - if (!viemChain) { - throw new Error(`Unsupported chain: ${chain}`); - } - return viemChain; +export function getViemChain(chain: SupportedSmartWalletChains | SupportedFaucetChains): Chain { + const viemChain = chainMap[chain]; + if (!viemChain) { + throw new Error(`Unsupported chain: ${chain}`); + } + return viemChain; } -const testnetChains = [ - "arbitrum-sepolia", - "base-sepolia", - "optimism-sepolia", - "polygon-amoy", -] as const; +const testnetChains = ["arbitrum-sepolia", "base-sepolia", "optimism-sepolia", "polygon-amoy"] as const; -export function getEnv( - chain: SupportedSmartWalletChains, -): "staging" | "production" { - return (testnetChains as readonly string[]).includes(chain) - ? "staging" - : "production"; +export function getEnv(chain: SupportedSmartWalletChains): "staging" | "production" { + return (testnetChains as readonly string[]).includes(chain) ? "staging" : "production"; } -const faucetChainIds = new Set( - faucetChains.map((chainName) => chainMap[chainName].id), -); +const faucetChainIds = new Set(faucetChains.map((chainName) => chainMap[chainName].id)); export function isChainSupportedByFaucet(chainId: number): boolean { - return faucetChainIds.has(chainId); + return faucetChainIds.has(chainId); } diff --git a/typescript/packages/wallets/crossmint/src/custodial.ts b/typescript/packages/wallets/crossmint/src/custodial.ts index 9d06be604..a9eb3101e 100644 --- a/typescript/packages/wallets/crossmint/src/custodial.ts +++ b/typescript/packages/wallets/crossmint/src/custodial.ts @@ -1,172 +1,146 @@ -import type { - SolanaReadRequest, - SolanaTransaction, - SolanaWalletClient, -} from "@goat-sdk/core"; -import { - type Connection, - PublicKey, - TransactionMessage, - VersionedTransaction, -} from "@solana/web3.js"; +import type { SolanaReadRequest, SolanaTransaction, SolanaWalletClient } from "@goat-sdk/core"; +import { type Connection, PublicKey, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; import bs58 from "bs58"; import { createCrossmintAPI } from "./api"; type CommonParameters = { - chain: "solana"; - connection: Connection; - env?: "staging" | "production"; + chain: "solana"; + connection: Connection; + env?: "staging" | "production"; }; type EmailLocatorParameters = CommonParameters & { - email: string; + email: string; }; type PhoneLocatorParameters = CommonParameters & { - phone: string; + phone: string; }; type UserIdLocatorParameters = CommonParameters & { - userId: number; + userId: number; }; type AddressLocatorParameters = CommonParameters & { - address: string; + address: string; }; type CustodialOptions = - | EmailLocatorParameters - | PhoneLocatorParameters - | UserIdLocatorParameters - | AddressLocatorParameters; + | EmailLocatorParameters + | PhoneLocatorParameters + | UserIdLocatorParameters + | AddressLocatorParameters; function getLocator(params: CustodialOptions): string | number { - if ("address" in params) return params.address; - if ("email" in params) return `email:${params.email}`; - if ("phone" in params) return `phone:${params.phone}`; - return `userId:${params.userId}`; + if ("address" in params) return params.address; + if ("email" in params) return `email:${params.email}`; + if ("phone" in params) return `phone:${params.phone}`; + return `userId:${params.userId}`; } export function custodialFactory(apiKey: string) { - return async function custodial( - params: CustodialOptions, - ): Promise { - const { connection, env = "staging" } = params; - - const locator = `${getLocator(params)}:solana-custodial-wallet`; - const client = createCrossmintAPI(apiKey, env); - const { address } = await client.getWallet(locator); - - return { - getAddress() { - return address; - }, - getChain() { - return { - type: "solana", - }; - }, - async signMessage(message: string) { - try { - const { id } = await client.signMessageForCustodialWallet( - locator, - message, - ); - - while (true) { - const latestSignature = await client.checkSignatureStatus( - id, - address, - ); - - if (latestSignature.status === "success") { - if (!latestSignature.outputSignature) { - throw new Error("Signature is undefined"); - } - - return { - signature: latestSignature.outputSignature, - }; - } - - if (latestSignature.status === "failed") { - throw new Error("Signature failed"); - } - - await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds - } - } catch (error) { - throw new Error(`Failed to sign message: ${error}`); - } - }, - async sendTransaction({ instructions }: SolanaTransaction) { - const latestBlockhash = - await connection.getLatestBlockhash("confirmed"); - const message = new TransactionMessage({ - // Placeholder payer key since Crossmint will override it - payerKey: new PublicKey("placeholder"), - recentBlockhash: latestBlockhash.blockhash, - instructions, - }).compileToV0Message(); - const transaction = new VersionedTransaction(message); - const serializedVersionedTransaction = transaction.serialize(); - const encodedVersionedTransaction = bs58.encode( - serializedVersionedTransaction, - ); - - const { id: transactionId } = - await client.createTransactionForCustodialWallet( - locator, - encodedVersionedTransaction, - ); - - while (true) { - const latestTransaction = await client.checkTransactionStatus( - locator, - transactionId, - ); - - if (latestTransaction.status === "success") { - console.log(`Transaction ${latestTransaction.status}`); - return { - hash: latestTransaction.onChain?.txId ?? "", - }; - } - - if (latestTransaction.status === "failed") { - throw new Error( - `Transaction failed: ${latestTransaction.onChain?.txId}`, - ); - } - - await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds - } - }, - async read(request: SolanaReadRequest) { - const { accountAddress } = request; - - const pubkey = new PublicKey(accountAddress); - const accountInfo = await connection.getAccountInfo(pubkey); - - if (!accountInfo) { - throw new Error(`Account ${accountAddress} not found`); - } - - return { - value: accountInfo, - }; - }, - async balanceOf(address: string) { - const pubkey = new PublicKey(address); - const balance = await connection.getBalance(pubkey); - - return { - value: BigInt(balance), - decimals: 9, - symbol: "SOL", - name: "Solana", - }; - }, - }; - }; + return async function custodial(params: CustodialOptions): Promise { + const { connection, env = "staging" } = params; + + const locator = `${getLocator(params)}:solana-custodial-wallet`; + const client = createCrossmintAPI(apiKey, env); + const { address } = await client.getWallet(locator); + + return { + getAddress() { + return address; + }, + getChain() { + return { + type: "solana", + }; + }, + async signMessage(message: string) { + try { + const { id } = await client.signMessageForCustodialWallet(locator, message); + + while (true) { + const latestSignature = await client.checkSignatureStatus(id, address); + + if (latestSignature.status === "success") { + if (!latestSignature.outputSignature) { + throw new Error("Signature is undefined"); + } + + return { + signature: latestSignature.outputSignature, + }; + } + + if (latestSignature.status === "failed") { + throw new Error("Signature failed"); + } + + await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds + } + } catch (error) { + throw new Error(`Failed to sign message: ${error}`); + } + }, + async sendTransaction({ instructions }: SolanaTransaction) { + const latestBlockhash = await connection.getLatestBlockhash("confirmed"); + const message = new TransactionMessage({ + // Placeholder payer key since Crossmint will override it + payerKey: new PublicKey("placeholder"), + recentBlockhash: latestBlockhash.blockhash, + instructions, + }).compileToV0Message(); + const transaction = new VersionedTransaction(message); + const serializedVersionedTransaction = transaction.serialize(); + const encodedVersionedTransaction = bs58.encode(serializedVersionedTransaction); + + const { id: transactionId } = await client.createTransactionForCustodialWallet( + locator, + encodedVersionedTransaction, + ); + + while (true) { + const latestTransaction = await client.checkTransactionStatus(locator, transactionId); + + if (latestTransaction.status === "success") { + console.log(`Transaction ${latestTransaction.status}`); + return { + hash: latestTransaction.onChain?.txId ?? "", + }; + } + + if (latestTransaction.status === "failed") { + throw new Error(`Transaction failed: ${latestTransaction.onChain?.txId}`); + } + + await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds + } + }, + async read(request: SolanaReadRequest) { + const { accountAddress } = request; + + const pubkey = new PublicKey(accountAddress); + const accountInfo = await connection.getAccountInfo(pubkey); + + if (!accountInfo) { + throw new Error(`Account ${accountAddress} not found`); + } + + return { + value: accountInfo, + }; + }, + async balanceOf(address: string) { + const pubkey = new PublicKey(address); + const balance = await connection.getBalance(pubkey); + + return { + value: BigInt(balance), + decimals: 9, + symbol: "SOL", + name: "Solana", + }; + }, + }; + }; } diff --git a/typescript/packages/wallets/crossmint/src/faucet.ts b/typescript/packages/wallets/crossmint/src/faucet.ts index 4a19c0c93..25ba1f4ef 100644 --- a/typescript/packages/wallets/crossmint/src/faucet.ts +++ b/typescript/packages/wallets/crossmint/src/faucet.ts @@ -31,15 +31,11 @@ export function faucetFactory(apiKey: string) { parameters: topUpBalanceParametersSchema, method: async ( walletClient: EVMWalletClient, - parameters: z.infer< - typeof topUpBalanceParametersSchema - > + parameters: z.infer, ) => { - const wallet = - parameters.wallet ?? walletClient.getAddress(); + const wallet = parameters.wallet ?? walletClient.getAddress(); - const resolvedWalletAddress = - await walletClient.resolveAddress(wallet); + const resolvedWalletAddress = await walletClient.resolveAddress(wallet); const network = walletClient.getChain(); @@ -50,9 +46,7 @@ export function faucetFactory(apiKey: string) { const chain = getTestnetChainNameById(network.id); if (!chain) { - throw new Error( - `Failed to top up balance: Unsupported chain ${network}` - ); + throw new Error(`Failed to top up balance: Unsupported chain ${network}`); } const options = { @@ -70,16 +64,14 @@ export function faucetFactory(apiKey: string) { const response = await fetch( `https://staging.crossmint.com/api/v1-alpha2/wallets/${resolvedWalletAddress}/balances`, - options + options, ); if (response.ok) { return "Balance topped up successfully"; } - throw new Error( - `Failed to top up balance: ${await response.text()}` - ); + throw new Error(`Failed to top up balance: ${await response.text()}`); }, }, ]; diff --git a/typescript/packages/wallets/crossmint/src/index.ts b/typescript/packages/wallets/crossmint/src/index.ts index 072fae7ed..22667032f 100644 --- a/typescript/packages/wallets/crossmint/src/index.ts +++ b/typescript/packages/wallets/crossmint/src/index.ts @@ -3,11 +3,11 @@ import { faucetFactory } from "./faucet"; import { smartWalletFactory } from "./smart-wallet"; function crossmint(apiKey: string) { - return { - custodial: custodialFactory(apiKey), - smartwallet: smartWalletFactory(apiKey), - faucet: faucetFactory(apiKey), - }; + return { + custodial: custodialFactory(apiKey), + smartwallet: smartWalletFactory(apiKey), + faucet: faucetFactory(apiKey), + }; } export { crossmint }; diff --git a/typescript/packages/wallets/crossmint/src/smart-wallet.ts b/typescript/packages/wallets/crossmint/src/smart-wallet.ts index e936052bb..a26931493 100644 --- a/typescript/packages/wallets/crossmint/src/smart-wallet.ts +++ b/typescript/packages/wallets/crossmint/src/smart-wallet.ts @@ -1,9 +1,4 @@ -import type { - EVMReadRequest, - EVMSmartWalletClient, - EVMTransaction, - EVMTypedData, -} from "@goat-sdk/core"; +import type { EVMReadRequest, EVMSmartWalletClient, EVMTransaction, EVMTypedData } from "@goat-sdk/core"; import type { Abi } from "abitype"; import { http, createPublicClient, encodeFunctionData } from "viem"; @@ -11,357 +6,320 @@ import { privateKeyToAccount } from "viem/accounts"; import { mainnet } from "viem/chains"; import { normalize } from "viem/ens"; import { createCrossmintAPI } from "./api"; -import { - type SupportedSmartWalletChains, - getEnv, - getViemChain, -} from "./chains"; +import { type SupportedSmartWalletChains, getEnv, getViemChain } from "./chains"; export type CustodialSigner = `0x${string}`; export type KeyPairSigner = { - secretKey: `0x${string}`; + secretKey: `0x${string}`; }; type EmailLinkedUser = { - email: string; + email: string; }; type PhoneLinkedUser = { - phone: string; + phone: string; }; type UserIdLinkedUser = { - userId: number; + userId: number; }; export type SmartWalletOptions = { - signer: CustodialSigner | KeyPairSigner; - address?: string; - linkedUser?: EmailLinkedUser | PhoneLinkedUser | UserIdLinkedUser; - chain: SupportedSmartWalletChains; - provider: string; - options?: { - ensProvider?: string; - }; + signer: CustodialSigner | KeyPairSigner; + address?: string; + linkedUser?: EmailLinkedUser | PhoneLinkedUser | UserIdLinkedUser; + chain: SupportedSmartWalletChains; + provider: string; + options?: { + ensProvider?: string; + }; }; export function smartWalletFactory(apiKey: string) { - return async function smartwallet( - params: SmartWalletOptions, - ): Promise { - const { - signer, - linkedUser, - chain, - provider, - address: providedAddress, - } = params; - - const hasCustodialSigner = typeof signer === "string"; - const getLocator = () => { - if (linkedUser) { - if ("email" in linkedUser) { - return `email:${linkedUser.email}:evm-smart-wallet`; - } - if ("phone" in linkedUser) { - return `phone:${linkedUser.phone}:evm-smart-wallet`; - } - if ("userId" in linkedUser) { - return `userId:${linkedUser.userId}:evm-smart-wallet`; - } - } - - if (!providedAddress) { - throw new Error( - "Smart Wallet address is required if no linked user is provided", - ); - } - - return providedAddress; - }; - - const locator = getLocator(); - const client = createCrossmintAPI(apiKey, getEnv(chain)); - const { address } = await client.getWallet(locator); - - const viemClient = createPublicClient({ - chain: getViemChain(chain), - transport: http(provider), - }); - - const signerAccount = hasCustodialSigner - ? null - : privateKeyToAccount(signer.secretKey); - - const ensClient = createPublicClient({ - chain: mainnet, - transport: http(params?.options?.ensProvider ?? ""), - }); - - const resolveAddressImpl = async (address: string) => { - console.log("Address", address); - if (/^0x[a-fA-F0-9]{40}$/.test(address)) { - return address as `0x${string}`; - } - - if (!ensClient) { - throw new Error("ENS provider is not configured."); - } - - try { - const resolvedAddress = (await ensClient.getEnsAddress({ - name: normalize(address), - })) as `0x${string}`; - if (!resolvedAddress) { - throw new Error("ENS name could not be resolved."); - } - return resolvedAddress as `0x${string}`; - } catch (error) { - throw new Error(`Failed to resolve ENS name: ${error}`); - } - }; - - const sendBatchOfTransactions = async (transactions: EVMTransaction[]) => { - const transactionDatas = transactions.map((transaction) => { - const { - to: recipientAddress, - abi, - functionName, - args, - value, - } = transaction; - - return buildTransactionData({ - recipientAddress, - abi, - functionName, - args, - value, - }); - }); - - const transactionResponse = await client.createTransactionForSmartWallet( - address, - transactionDatas, - chain, - signerAccount?.address, - ); - - if (!hasCustodialSigner) { - const account = privateKeyToAccount(signer.secretKey); - const userOpHash = transactionResponse.approvals?.pending[0].message; - - if (!userOpHash) { - throw new Error("User operation hash is not available"); - } - const signature = await account.signMessage({ - message: { raw: userOpHash as `0x${string}` }, - }); - - await client.approveTransaction(locator, transactionResponse.id, [ - { - signature, - signer: `evm-keypair:${signerAccount?.address}`, - }, - ]); - } - - while (true) { - const latestTransaction = await client.checkTransactionStatus( - locator, - transactionResponse.id, - ); - - if ( - latestTransaction.status === "success" || - latestTransaction.status === "failed" - ) { - return { - hash: latestTransaction.onChain?.txId ?? "", - status: latestTransaction.status, - }; - } - - await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 2 seconds - } - }; - - return { - getAddress() { - return address; - }, - getChain() { - return { - type: "evm", - id: viemClient.chain?.id ?? 0, - }; - }, - resolveAddress: resolveAddressImpl, - async signMessage(message: string) { - const { id: signatureId, approvals } = - await client.signMessageForSmartWallet( - address, - message, - chain, - signerAccount?.address, - ); - - if (!hasCustodialSigner) { - const account = privateKeyToAccount(signer.secretKey); - const toSign = approvals?.pending[0].message; - const signature = await account.signMessage({ - message: { raw: toSign as `0x${string}` }, - }); - - await client.approveSignatureForSmartWallet( - signatureId, - address, - `evm-keypair:${signerAccount?.address}`, - signature, - ); - } - - while (true) { - const latestSignature = await client.checkSignatureStatus( - signatureId, - address, - ); - - if (latestSignature.status === "success") { - if (!latestSignature.outputSignature) { - throw new Error("Signature is undefined"); - } - - return { - signature: latestSignature.outputSignature, - }; - } - - if (latestSignature.status === "failed") { - throw new Error("Signature failed"); - } - - await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 2 seconds - } - }, - async signTypedData(data: EVMTypedData) { - const { id: signatureId, approvals } = - await client.signTypedDataForSmartWallet( - address, - data, - chain, - signerAccount?.address, - ); - - if (!hasCustodialSigner) { - const account = privateKeyToAccount(signer.secretKey); - const toSign = approvals?.pending[0].message; - const signature = await account.signMessage({ - message: { raw: toSign as `0x${string}` }, - }); - - await client.approveSignatureForSmartWallet( - signatureId, - address, - `evm-keypair:${signerAccount?.address}`, - signature, - ); - } - - while (true) { - const latestSignature = await client.checkSignatureStatus( - signatureId, - address, - ); - - if (latestSignature.status === "success") { - if (!latestSignature.outputSignature) { - throw new Error("Signature is undefined"); - } - - return { - signature: latestSignature.outputSignature, - }; - } - - if (latestSignature.status === "failed") { - throw new Error("Signature failed"); - } - - await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 2 seconds - } - }, - async sendTransaction(transaction: EVMTransaction) { - return await sendBatchOfTransactions([transaction]); - }, - async sendBatchOfTransactions(transactions: EVMTransaction[]) { - return await sendBatchOfTransactions(transactions); - }, - async read(request: EVMReadRequest) { - const { address: contractAddress, abi, functionName, args } = request; - - const resolvedContractAddress = - await resolveAddressImpl(contractAddress); - - if (!abi) throw new Error("Read request must include ABI for EVM"); - - const result = await viemClient.readContract({ - address: resolvedContractAddress, - abi, - functionName, - args, - }); - - return { - value: result, - }; - }, - async balanceOf(address: string) { - const resolvedAddress = await resolveAddressImpl(address); - const balance = await viemClient.getBalance({ - address: resolvedAddress, - }); - - return { - decimals: 18, - symbol: "ETH", - name: "Ethereum", - value: balance, - }; - }, - }; - }; + return async function smartwallet(params: SmartWalletOptions): Promise { + const { signer, linkedUser, chain, provider, address: providedAddress } = params; + + const hasCustodialSigner = typeof signer === "string"; + const getLocator = () => { + if (linkedUser) { + if ("email" in linkedUser) { + return `email:${linkedUser.email}:evm-smart-wallet`; + } + if ("phone" in linkedUser) { + return `phone:${linkedUser.phone}:evm-smart-wallet`; + } + if ("userId" in linkedUser) { + return `userId:${linkedUser.userId}:evm-smart-wallet`; + } + } + + if (!providedAddress) { + throw new Error("Smart Wallet address is required if no linked user is provided"); + } + + return providedAddress; + }; + + const locator = getLocator(); + const client = createCrossmintAPI(apiKey, getEnv(chain)); + const { address } = await client.getWallet(locator); + + const viemClient = createPublicClient({ + chain: getViemChain(chain), + transport: http(provider), + }); + + const signerAccount = hasCustodialSigner ? null : privateKeyToAccount(signer.secretKey); + + const ensClient = createPublicClient({ + chain: mainnet, + transport: http(params?.options?.ensProvider ?? ""), + }); + + const resolveAddressImpl = async (address: string) => { + console.log("Address", address); + if (/^0x[a-fA-F0-9]{40}$/.test(address)) { + return address as `0x${string}`; + } + + if (!ensClient) { + throw new Error("ENS provider is not configured."); + } + + try { + const resolvedAddress = (await ensClient.getEnsAddress({ + name: normalize(address), + })) as `0x${string}`; + if (!resolvedAddress) { + throw new Error("ENS name could not be resolved."); + } + return resolvedAddress as `0x${string}`; + } catch (error) { + throw new Error(`Failed to resolve ENS name: ${error}`); + } + }; + + const sendBatchOfTransactions = async (transactions: EVMTransaction[]) => { + const transactionDatas = transactions.map((transaction) => { + const { to: recipientAddress, abi, functionName, args, value } = transaction; + + return buildTransactionData({ + recipientAddress, + abi, + functionName, + args, + value, + }); + }); + + const transactionResponse = await client.createTransactionForSmartWallet( + address, + transactionDatas, + chain, + signerAccount?.address, + ); + + if (!hasCustodialSigner) { + const account = privateKeyToAccount(signer.secretKey); + const userOpHash = transactionResponse.approvals?.pending[0].message; + + if (!userOpHash) { + throw new Error("User operation hash is not available"); + } + const signature = await account.signMessage({ + message: { raw: userOpHash as `0x${string}` }, + }); + + await client.approveTransaction(locator, transactionResponse.id, [ + { + signature, + signer: `evm-keypair:${signerAccount?.address}`, + }, + ]); + } + + while (true) { + const latestTransaction = await client.checkTransactionStatus(locator, transactionResponse.id); + + if (latestTransaction.status === "success" || latestTransaction.status === "failed") { + return { + hash: latestTransaction.onChain?.txId ?? "", + status: latestTransaction.status, + }; + } + + await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 2 seconds + } + }; + + return { + getAddress() { + return address; + }, + getChain() { + return { + type: "evm", + id: viemClient.chain?.id ?? 0, + }; + }, + resolveAddress: resolveAddressImpl, + async signMessage(message: string) { + const { id: signatureId, approvals } = await client.signMessageForSmartWallet( + address, + message, + chain, + signerAccount?.address, + ); + + if (!hasCustodialSigner) { + const account = privateKeyToAccount(signer.secretKey); + const toSign = approvals?.pending[0].message; + const signature = await account.signMessage({ + message: { raw: toSign as `0x${string}` }, + }); + + await client.approveSignatureForSmartWallet( + signatureId, + address, + `evm-keypair:${signerAccount?.address}`, + signature, + ); + } + + while (true) { + const latestSignature = await client.checkSignatureStatus(signatureId, address); + + if (latestSignature.status === "success") { + if (!latestSignature.outputSignature) { + throw new Error("Signature is undefined"); + } + + return { + signature: latestSignature.outputSignature, + }; + } + + if (latestSignature.status === "failed") { + throw new Error("Signature failed"); + } + + await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 2 seconds + } + }, + async signTypedData(data: EVMTypedData) { + const { id: signatureId, approvals } = await client.signTypedDataForSmartWallet( + address, + data, + chain, + signerAccount?.address, + ); + + if (!hasCustodialSigner) { + const account = privateKeyToAccount(signer.secretKey); + const toSign = approvals?.pending[0].message; + const signature = await account.signMessage({ + message: { raw: toSign as `0x${string}` }, + }); + + await client.approveSignatureForSmartWallet( + signatureId, + address, + `evm-keypair:${signerAccount?.address}`, + signature, + ); + } + + while (true) { + const latestSignature = await client.checkSignatureStatus(signatureId, address); + + if (latestSignature.status === "success") { + if (!latestSignature.outputSignature) { + throw new Error("Signature is undefined"); + } + + return { + signature: latestSignature.outputSignature, + }; + } + + if (latestSignature.status === "failed") { + throw new Error("Signature failed"); + } + + await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 2 seconds + } + }, + async sendTransaction(transaction: EVMTransaction) { + return await sendBatchOfTransactions([transaction]); + }, + async sendBatchOfTransactions(transactions: EVMTransaction[]) { + return await sendBatchOfTransactions(transactions); + }, + async read(request: EVMReadRequest) { + const { address: contractAddress, abi, functionName, args } = request; + + const resolvedContractAddress = await resolveAddressImpl(contractAddress); + + if (!abi) throw new Error("Read request must include ABI for EVM"); + + const result = await viemClient.readContract({ + address: resolvedContractAddress, + abi, + functionName, + args, + }); + + return { + value: result, + }; + }, + async balanceOf(address: string) { + const resolvedAddress = await resolveAddressImpl(address); + const balance = await viemClient.getBalance({ + address: resolvedAddress, + }); + + return { + decimals: 18, + symbol: "ETH", + name: "Ethereum", + value: balance, + }; + }, + }; + }; } function buildTransactionData({ - recipientAddress, - abi, - functionName, - args, - value, + recipientAddress, + abi, + functionName, + args, + value, }: { - recipientAddress: string; - abi?: Abi; - functionName?: string; - args?: unknown[]; - value?: bigint; + recipientAddress: string; + abi?: Abi; + functionName?: string; + args?: unknown[]; + value?: bigint; }) { - if (!abi) { - return { - to: recipientAddress, - value: value?.toString() ?? "0", - data: "0x", - }; - } - - if (!functionName) { - throw new Error("Function name is required"); - } - - return { - to: recipientAddress, - value: value?.toString() ?? "0", - data: encodeFunctionData({ abi, functionName, args }), - }; + if (!abi) { + return { + to: recipientAddress, + value: value?.toString() ?? "0", + data: "0x", + }; + } + + if (!functionName) { + throw new Error("Function name is required"); + } + + return { + to: recipientAddress, + value: value?.toString() ?? "0", + data: encodeFunctionData({ abi, functionName, args }), + }; } diff --git a/typescript/packages/wallets/crossmint/tsconfig.json b/typescript/packages/wallets/crossmint/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/wallets/crossmint/tsconfig.json +++ b/typescript/packages/wallets/crossmint/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/wallets/crossmint/tsup.config.ts b/typescript/packages/wallets/crossmint/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/wallets/crossmint/tsup.config.ts +++ b/typescript/packages/wallets/crossmint/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/wallets/crossmint/turbo.json b/typescript/packages/wallets/crossmint/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/wallets/crossmint/turbo.json +++ b/typescript/packages/wallets/crossmint/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/wallets/solana/package.json b/typescript/packages/wallets/solana/package.json index 19f8a5fa2..4f48432a6 100644 --- a/typescript/packages/wallets/solana/package.json +++ b/typescript/packages/wallets/solana/package.json @@ -1,49 +1,34 @@ { - "name": "@goat-sdk/wallet-solana", - "version": "0.1.3", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "@solana/web3.js": "1.95.8", - "bs58": "^6.0.0", - "tweetnacl": "^1.0.3" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*", - "@solana/web3.js": "1.95.8" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/wallet-solana", + "version": "0.1.3", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "@solana/web3.js": "1.95.8", + "bs58": "^6.0.0", + "tweetnacl": "^1.0.3" + }, + "peerDependencies": { + "@goat-sdk/core": "workspace:*", + "@solana/web3.js": "1.95.8" + }, + "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/wallets/solana/src/index.ts b/typescript/packages/wallets/solana/src/index.ts index c6fa107b8..70d935287 100644 --- a/typescript/packages/wallets/solana/src/index.ts +++ b/typescript/packages/wallets/solana/src/index.ts @@ -1,85 +1,72 @@ -import type { - SolanaReadRequest, - SolanaTransaction, - SolanaWalletClient, -} from "@goat-sdk/core"; +import type { SolanaReadRequest, SolanaTransaction, SolanaWalletClient } from "@goat-sdk/core"; -import { - type Connection, - type Keypair, - PublicKey, - TransactionMessage, - VersionedTransaction, -} from "@solana/web3.js"; +import { type Connection, type Keypair, PublicKey, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; import nacl from "tweetnacl"; export type SolanaWalletOptions = { - keypair: Keypair; - connection: Connection; + keypair: Keypair; + connection: Connection; }; -export function solana({ - connection, - keypair, -}: SolanaWalletOptions): SolanaWalletClient { - return { - getAddress: () => keypair.publicKey.toBase58(), - getChain() { - return { - type: "solana", - }; - }, - async signMessage(message: string) { - const messageBytes = Buffer.from(message); - const signature = nacl.sign.detached(messageBytes, keypair.secretKey); - return { - signature: Buffer.from(signature).toString("hex"), - }; - }, - async sendTransaction({ instructions }: SolanaTransaction) { - const latestBlockhash = await connection.getLatestBlockhash("confirmed"); - const message = new TransactionMessage({ - payerKey: keypair.publicKey, - recentBlockhash: latestBlockhash.blockhash, - instructions, - }).compileToV0Message(); - const transaction = new VersionedTransaction(message); +export function solana({ connection, keypair }: SolanaWalletOptions): SolanaWalletClient { + return { + getAddress: () => keypair.publicKey.toBase58(), + getChain() { + return { + type: "solana", + }; + }, + async signMessage(message: string) { + const messageBytes = Buffer.from(message); + const signature = nacl.sign.detached(messageBytes, keypair.secretKey); + return { + signature: Buffer.from(signature).toString("hex"), + }; + }, + async sendTransaction({ instructions }: SolanaTransaction) { + const latestBlockhash = await connection.getLatestBlockhash("confirmed"); + const message = new TransactionMessage({ + payerKey: keypair.publicKey, + recentBlockhash: latestBlockhash.blockhash, + instructions, + }).compileToV0Message(); + const transaction = new VersionedTransaction(message); - transaction.sign([keypair]); + transaction.sign([keypair]); - const txid = await connection.sendTransaction(transaction, { - maxRetries: 5, - }); + const txid = await connection.sendTransaction(transaction, { + maxRetries: 5, + }); - return { - hash: txid, - }; - }, - async read(request: SolanaReadRequest) { - const { accountAddress } = request; + return { + hash: txid, + }; + }, + async read(request: SolanaReadRequest) { + const { accountAddress } = request; - const pubkey = new PublicKey(accountAddress); - const accountInfo = await connection.getAccountInfo(pubkey); + const pubkey = new PublicKey(accountAddress); + const accountInfo = await connection.getAccountInfo(pubkey); - if (!accountInfo) { - throw new Error(`Account ${accountAddress} not found`); - } + if (!accountInfo) { + throw new Error(`Account ${accountAddress} not found`); + } - return { - value: accountInfo, - }; - }, - async balanceOf(address: string) { - const pubkey = new PublicKey(address); - const balance = await connection.getBalance(pubkey); + return { + value: accountInfo, + }; + }, + async balanceOf(address: string) { + const pubkey = new PublicKey(address); + const balance = await connection.getBalance(pubkey); - return { - decimals: 9, - symbol: "SOL", - name: "Solana", - value: BigInt(balance), - }; - }, - }; + return { + decimals: 9, + symbol: "SOL", + name: "Solana", + value: BigInt(balance), + }; + }, + }; } diff --git a/typescript/packages/wallets/solana/tsconfig.json b/typescript/packages/wallets/solana/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/wallets/solana/tsconfig.json +++ b/typescript/packages/wallets/solana/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/wallets/solana/tsup.config.ts b/typescript/packages/wallets/solana/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/wallets/solana/tsup.config.ts +++ b/typescript/packages/wallets/solana/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/wallets/solana/turbo.json b/typescript/packages/wallets/solana/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/wallets/solana/turbo.json +++ b/typescript/packages/wallets/solana/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/packages/wallets/viem/package.json b/typescript/packages/wallets/viem/package.json index c10df3a6d..67c84bc85 100644 --- a/typescript/packages/wallets/viem/package.json +++ b/typescript/packages/wallets/viem/package.json @@ -1,47 +1,32 @@ { - "name": "@goat-sdk/wallet-viem", - "version": "0.1.3", - "sideEffects": false, - "files": ["dist/**/*", "README.md", "package.json"], - "scripts": { - "build": "tsup", - "clean": "rm -rf dist", - "test": "vitest" - }, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "devDependencies": { - "@types/node": "^22.7.4", - "globals": "^15.12.0", - "ts-node": "^10.9.2", - "tsup": "^8.3.5", - "typescript": "^5.6.3", - "vitest": "^2.1.5" - }, - "dependencies": { - "@goat-sdk/core": "workspace:*", - "viem": "^2.21.49" - }, - "peerDependencies": { - "@goat-sdk/core": "workspace:*", - "viem": "^2.21.49" - }, - "engines": { - "node": ">=20.12.2 <21", - "npm": "please-use-pnpm", - "pnpm": ">=9", - "yarn": "please-use-pnpm" - }, - "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"], - "packageManager": "pnpm@9.14.2" + "name": "@goat-sdk/wallet-viem", + "version": "0.1.3", + "sideEffects": false, + "files": ["dist/**/*", "README.md", "package.json"], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist", + "test": "vitest run --passWithNoTests" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "dependencies": { + "@goat-sdk/core": "workspace:*", + "viem": "^2.21.49" + }, + "peerDependencies": { + "@goat-sdk/core": "workspace:*", + "viem": "^2.21.49" + }, + "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/wallets/viem/src/index.ts b/typescript/packages/wallets/viem/src/index.ts index 230dfe55b..0929e18ce 100644 --- a/typescript/packages/wallets/viem/src/index.ts +++ b/typescript/packages/wallets/viem/src/index.ts @@ -1,152 +1,147 @@ -import type { - EVMReadRequest, - EVMTransaction, - EVMTypedData, - EVMWalletClient, -} from "@goat-sdk/core"; +import type { EVMReadRequest, EVMTransaction, EVMTypedData, EVMWalletClient } from "@goat-sdk/core"; import { publicActions } from "viem"; import type { WalletClient as ViemWalletClient } from "viem"; import { normalize } from "viem/ens"; export function viem(client: ViemWalletClient): EVMWalletClient { - const publicClient = client.extend(publicActions); - - return { - getAddress: () => client.account?.address ?? "", - getChain() { - return { - type: "evm", - id: client.chain?.id ?? 0, - }; - }, - async resolveAddress(address: string) { - if (/^0x[a-fA-F0-9]{40}$/.test(address)) { - return address as `0x${string}`; - } - - try { - const resolvedAddress = (await publicClient.getEnsAddress({ - name: normalize(address), - })) as `0x${string}`; - if (!resolvedAddress) { - throw new Error("ENS name could not be resolved."); - } - return resolvedAddress as `0x${string}`; - } catch (error) { - throw new Error(`Failed to resolve ENS name: ${error}`); - } - }, - async signMessage(message: string) { - if (!client.account) throw new Error("No account connected"); - const signature = await client.signMessage({ - message, - account: client.account, - }); - - return { - signature, - }; - }, - async signTypedData(data: EVMTypedData) { - if (!client.account) throw new Error("No account connected"); - - const signature = await client.signTypedData({ - domain: data.domain, - types: data.types, - primaryType: data.primaryType, - message: data.message, - account: client.account, - }); - - return { - signature, - }; - }, - async sendTransaction(transaction: EVMTransaction) { - const { to, abi, functionName, args, value } = transaction; - - const toAddress = await this.resolveAddress(to); - if (!client.account) throw new Error("No account connected"); - - if (!abi) { - const tx = await client.sendTransaction({ - account: client.account, - to: toAddress, - chain: client.chain, - value, - }); - - const transaction = await publicClient.waitForTransactionReceipt({ - hash: tx, - }); - - return { - hash: transaction.transactionHash, - status: transaction.status, - }; - } - - if (!functionName) { - throw new Error("Function name is required"); - } - - await publicClient.simulateContract({ - account: client.account, - address: toAddress, - abi, - functionName, - args, - chain: client.chain, - }); - const hash = await client.writeContract({ - account: client.account, - address: toAddress, - abi, - functionName, - args, - chain: client.chain, - value, - }); - - const t = await publicClient.waitForTransactionReceipt({ - hash: hash, - }); - - return { - hash: t.transactionHash, - status: t.status, - }; - }, - async read(request: EVMReadRequest) { - const { address, abi, functionName, args } = request; - - if (!abi) throw new Error("Read request must include ABI for EVM"); - - const result = await publicClient.readContract({ - address: await this.resolveAddress(address), - abi, - functionName, - args, - }); - - return { - value: result, - }; - }, - async balanceOf(address: string) { - const resolvedAddress = await this.resolveAddress(address); - - const balance = await publicClient.getBalance({ - address: resolvedAddress, - }); - - return { - value: balance, - decimals: 18, - symbol: "ETH", - name: "Ether", - }; - }, - }; + const publicClient = client.extend(publicActions); + + return { + getAddress: () => client.account?.address ?? "", + getChain() { + return { + type: "evm", + id: client.chain?.id ?? 0, + }; + }, + async resolveAddress(address: string) { + if (/^0x[a-fA-F0-9]{40}$/.test(address)) { + return address as `0x${string}`; + } + + try { + const resolvedAddress = (await publicClient.getEnsAddress({ + name: normalize(address), + })) as `0x${string}`; + if (!resolvedAddress) { + throw new Error("ENS name could not be resolved."); + } + return resolvedAddress as `0x${string}`; + } catch (error) { + throw new Error(`Failed to resolve ENS name: ${error}`); + } + }, + async signMessage(message: string) { + if (!client.account) throw new Error("No account connected"); + const signature = await client.signMessage({ + message, + account: client.account, + }); + + return { + signature, + }; + }, + async signTypedData(data: EVMTypedData) { + if (!client.account) throw new Error("No account connected"); + + const signature = await client.signTypedData({ + domain: data.domain, + types: data.types, + primaryType: data.primaryType, + message: data.message, + account: client.account, + }); + + return { + signature, + }; + }, + async sendTransaction(transaction: EVMTransaction) { + const { to, abi, functionName, args, value } = transaction; + + const toAddress = await this.resolveAddress(to); + if (!client.account) throw new Error("No account connected"); + + if (!abi) { + const tx = await client.sendTransaction({ + account: client.account, + to: toAddress, + chain: client.chain, + value, + }); + + const transaction = await publicClient.waitForTransactionReceipt({ + hash: tx, + }); + + return { + hash: transaction.transactionHash, + status: transaction.status, + }; + } + + if (!functionName) { + throw new Error("Function name is required"); + } + + await publicClient.simulateContract({ + account: client.account, + address: toAddress, + abi, + functionName, + args, + chain: client.chain, + }); + const hash = await client.writeContract({ + account: client.account, + address: toAddress, + abi, + functionName, + args, + chain: client.chain, + value, + }); + + const t = await publicClient.waitForTransactionReceipt({ + hash: hash, + }); + + return { + hash: t.transactionHash, + status: t.status, + }; + }, + async read(request: EVMReadRequest) { + const { address, abi, functionName, args } = request; + + if (!abi) throw new Error("Read request must include ABI for EVM"); + + const result = await publicClient.readContract({ + address: await this.resolveAddress(address), + abi, + functionName, + args, + }); + + return { + value: result, + }; + }, + async balanceOf(address: string) { + const resolvedAddress = await this.resolveAddress(address); + + const balance = await publicClient.getBalance({ + address: resolvedAddress, + }); + + return { + value: balance, + decimals: 18, + symbol: "ETH", + name: "Ether", + }; + }, + }; } diff --git a/typescript/packages/wallets/viem/tsconfig.json b/typescript/packages/wallets/viem/tsconfig.json index a7ebc994a..b4ae67c1f 100644 --- a/typescript/packages/wallets/viem/tsconfig.json +++ b/typescript/packages/wallets/viem/tsconfig.json @@ -1,6 +1,6 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/typescript/packages/wallets/viem/tsup.config.ts b/typescript/packages/wallets/viem/tsup.config.ts index 7a731ab37..2d38789ad 100644 --- a/typescript/packages/wallets/viem/tsup.config.ts +++ b/typescript/packages/wallets/viem/tsup.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from "tsup"; import { treeShakableConfig } from "../../../tsup.config.base"; export default defineConfig({ - ...treeShakableConfig, + ...treeShakableConfig, }); diff --git a/typescript/packages/wallets/viem/turbo.json b/typescript/packages/wallets/viem/turbo.json index 557c33b87..45f951676 100644 --- a/typescript/packages/wallets/viem/turbo.json +++ b/typescript/packages/wallets/viem/turbo.json @@ -1,16 +1,11 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "tasks": { - "build": { - "inputs": [ - "src/**", - "tsup.config.ts", - "!./**/*.test.{ts,tsx}", - "tsconfig.json" - ], - "dependsOn": ["^build"], - "outputs": ["dist/**"] - } - } + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "inputs": ["src/**", "tsup.config.ts", "!./**/*.test.{ts,tsx}", "tsconfig.json"], + "dependsOn": ["^build"], + "outputs": ["dist/**"] + } + } } diff --git a/typescript/pnpm-lock.yaml b/typescript/pnpm-lock.yaml index b1d87d530..80113b95f 100644 --- a/typescript/pnpm-lock.yaml +++ b/typescript/pnpm-lock.yaml @@ -69,9 +69,6 @@ importers: specifier: ^2.13.3 version: 2.13.3(@tanstack/query-core@5.62.2)(@tanstack/react-query@5.62.2(react@19.0.0-rc-66855b96-20241106))(@types/react@18.3.12)(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.21.49(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) devDependencies: - '@types/node': - specifier: ^20 - version: 20.17.9 '@types/react': specifier: ^18 version: 18.3.12 @@ -83,10 +80,7 @@ importers: version: 8.4.49 tailwindcss: specifier: ^3.4.1 - version: 3.4.16(ts-node@10.9.2(@types/node@20.17.9)(typescript@5.6.3)) - typescript: - specifier: ^5 - version: 5.6.3 + version: 3.4.16(ts-node@10.9.2(@types/node@22.9.1)(typescript@5.6.3)) examples/langchain/viem: dependencies: @@ -117,10 +111,6 @@ importers: viem: specifier: 2.21.49 version: 2.21.49(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 examples/vercel-ai/coingecko: dependencies: @@ -182,10 +172,6 @@ importers: viem: specifier: 2.21.49 version: 2.21.49(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) - devDependencies: - '@types/node': - specifier: ^22.9.1 - version: 22.9.1 examples/vercel-ai/crossmint-solana-custodial-wallets: dependencies: @@ -216,10 +202,6 @@ importers: viem: specifier: 2.21.49 version: 2.21.49(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) - devDependencies: - '@types/node': - specifier: ^22.9.1 - version: 22.9.1 examples/vercel-ai/polymarket: dependencies: @@ -247,10 +229,6 @@ importers: viem: specifier: 2.21.49 version: 2.21.49(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 examples/vercel-ai/solana: dependencies: @@ -281,10 +259,6 @@ importers: dotenv: specifier: ^16.4.5 version: 16.4.5 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 examples/vercel-ai/viem: dependencies: @@ -312,10 +286,6 @@ importers: viem: specifier: 2.21.49 version: 2.21.49(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 packages/adapters/eleven-labs: dependencies: @@ -325,25 +295,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/adapters/eliza: dependencies: @@ -356,25 +307,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/adapters/langchain: dependencies: @@ -387,25 +319,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/adapters/vercel-ai: dependencies: @@ -418,25 +331,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/core: dependencies: @@ -452,25 +346,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/plugins/coingecko: dependencies: @@ -514,25 +389,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/plugins/polymarket: dependencies: @@ -548,25 +404,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/wallets/crossmint: dependencies: @@ -588,25 +425,6 @@ importers: zod: specifier: ^3.23.8 version: 3.23.8 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/wallets/solana: dependencies: @@ -622,25 +440,6 @@ importers: tweetnacl: specifier: ^1.0.3 version: 1.0.3 - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages/wallets/viem: dependencies: @@ -650,25 +449,6 @@ importers: viem: specifier: ^2.21.49 version: 2.21.49(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) - devDependencies: - '@types/node': - specifier: ^22.7.4 - version: 22.9.1 - globals: - specifier: ^15.12.0 - version: 15.12.0 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) - tsup: - specifier: ^8.3.5 - version: 8.3.5(jiti@2.4.1)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@types/node@22.9.1) packages: @@ -2119,9 +1899,6 @@ packages: '@types/node@18.19.65': resolution: {integrity: sha512-Ay5BZuO1UkTmVHzZJNvZKw/E+iB3GQABb6kijEz89w2JrfhNA+M/ebp18pfz9Gqe9ywhMC8AA8yC01lZq48J+Q==} - '@types/node@20.17.9': - resolution: {integrity: sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==} - '@types/node@22.9.1': resolution: {integrity: sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==} @@ -5000,7 +4777,7 @@ snapshots: transitivePeerDependencies: - zod - '@ai16z/adapter-sqlite@0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0)': + '@ai16z/adapter-sqlite@0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0)': dependencies: '@ai16z/eliza': 0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0) '@types/better-sqlite3': 7.6.11 @@ -5019,7 +4796,6 @@ snapshots: - '@langchain/mistralai' - '@langchain/ollama' - axios - - bufferutil - cheerio - encoding - handlebars @@ -5030,10 +4806,9 @@ snapshots: - supports-color - svelte - typeorm - - utf-8-validate - vue - '@ai16z/adapter-sqljs@0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0)': + '@ai16z/adapter-sqljs@0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0)': dependencies: '@ai16z/eliza': 0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0) '@types/sql.js': 1.4.9 @@ -5052,7 +4827,6 @@ snapshots: - '@langchain/mistralai' - '@langchain/ollama' - axios - - bufferutil - cheerio - encoding - handlebars @@ -5063,7 +4837,6 @@ snapshots: - supports-color - svelte - typeorm - - utf-8-validate - vue '@ai16z/adapter-supabase@0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0)': @@ -5104,8 +4877,8 @@ snapshots: '@ai-sdk/google-vertex': 0.0.42(@google-cloud/vertexai@1.9.0)(zod@3.23.8) '@ai-sdk/groq': 0.0.3(zod@3.23.8) '@ai-sdk/openai': 1.0.0-canary.3(zod@3.23.8) - '@ai16z/adapter-sqlite': 0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0) - '@ai16z/adapter-sqljs': 0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0) + '@ai16z/adapter-sqlite': 0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0) + '@ai16z/adapter-sqljs': 0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0) '@ai16z/adapter-supabase': 0.1.4-alpha.3(@google-cloud/vertexai@1.9.0)(@langchain/core@0.3.18(openai@4.69.0(zod@3.23.8)))(bufferutil@4.0.8)(react@19.0.0-rc-66855b96-20241106)(sswr@2.1.0(svelte@5.2.12))(svelte@5.2.12)(utf-8-validate@5.0.10)(vue@3.5.13(typescript@5.6.3))(whatwg-url@7.1.0) '@anthropic-ai/sdk': 0.30.1 '@types/uuid': 10.0.0 @@ -6511,10 +6284,6 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@20.17.9': - dependencies: - undici-types: 6.19.8 - '@types/node@22.9.1': dependencies: undici-types: 6.19.8 @@ -8591,13 +8360,13 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.4.49 - postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@20.17.9)(typescript@5.6.3)): + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@22.9.1)(typescript@5.6.3)): dependencies: lilconfig: 3.1.3 yaml: 2.6.1 optionalDependencies: postcss: 8.4.49 - ts-node: 10.9.2(@types/node@20.17.9)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@22.9.1)(typescript@5.6.3) postcss-load-config@6.0.1(jiti@2.4.1)(postcss@8.4.49)(yaml@2.6.1): dependencies: @@ -9061,7 +8830,7 @@ snapshots: system-architecture@0.1.0: {} - tailwindcss@3.4.16(ts-node@10.9.2(@types/node@20.17.9)(typescript@5.6.3)): + tailwindcss@3.4.16(ts-node@10.9.2(@types/node@22.9.1)(typescript@5.6.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -9080,7 +8849,7 @@ snapshots: postcss: 8.4.49 postcss-import: 15.1.0(postcss@8.4.49) postcss-js: 4.0.1(postcss@8.4.49) - postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@20.17.9)(typescript@5.6.3)) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@22.9.1)(typescript@5.6.3)) postcss-nested: 6.2.0(postcss@8.4.49) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -9175,25 +8944,6 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@20.17.9)(typescript@5.6.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.17.9 - acorn: 8.14.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.6.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optional: true - ts-node@10.9.2(@types/node@22.9.1)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 diff --git a/typescript/tsconfig.base.json b/typescript/tsconfig.base.json index 02a2dd4c2..3d89b4dec 100644 --- a/typescript/tsconfig.base.json +++ b/typescript/tsconfig.base.json @@ -1,20 +1,20 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "compilerOptions": { - "target": "ES2022", - "moduleResolution": "node", - "strict": true, - "esModuleInterop": true, - "isolatedModules": true, - "resolveJsonModule": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "dist", - "noEmitOnError": true, - "forceConsistentCasingInFileNames": true, - "lib": ["DOM", "ES6"], - "noErrorTruncation": true - }, - "exclude": ["node_modules", "examples"] + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "target": "ES2022", + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "isolatedModules": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "dist", + "noEmitOnError": true, + "forceConsistentCasingInFileNames": true, + "lib": ["DOM", "ES6"], + "noErrorTruncation": true + }, + "exclude": ["node_modules", "examples"] } diff --git a/typescript/tsup.config.base.ts b/typescript/tsup.config.base.ts index 22abe0356..ba0a908cc 100644 --- a/typescript/tsup.config.base.ts +++ b/typescript/tsup.config.base.ts @@ -1,15 +1,15 @@ import type { Options } from "tsup"; export const treeShakableConfig: Options = { - splitting: true, - clean: true, - format: ["esm", "cjs"], - bundle: true, - skipNodeModulesBundle: true, - watch: false, - shims: true, - entry: ["src/**/*.(ts|tsx)", "!src/**/*.test.(ts|tsx)"], - outDir: "dist", - dts: true, - sourcemap: true, + splitting: true, + clean: true, + format: ["esm", "cjs"], + bundle: true, + skipNodeModulesBundle: true, + watch: false, + shims: true, + entry: ["src/**/*.(ts|tsx)", "!src/**/*.test.(ts|tsx)"], + outDir: "dist", + dts: true, + sourcemap: true, }; diff --git a/typescript/turbo.json b/typescript/turbo.json index b379e4a49..3d0170405 100644 --- a/typescript/turbo.json +++ b/typescript/turbo.json @@ -1,20 +1,20 @@ { - "$schema": "https://turbo.build/schema.json", - "tasks": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**"] - }, - "test": { - "dependsOn": ["build"], - "outputs": [] - }, - "lint": { - "outputs": [] - }, - "clean": { - "cache": false, - "outputs": [] - } - } + "$schema": "https://turbo.build/schema.json", + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**"] + }, + "test": { + "dependsOn": ["build"], + "outputs": [] + }, + "lint": { + "outputs": [] + }, + "clean": { + "cache": false, + "outputs": [] + } + } }