From 469e2666a74cdaa350257a670035c3f190061dbc Mon Sep 17 00:00:00 2001 From: sayangel Date: Sun, 24 Nov 2024 15:22:27 -0800 Subject: [PATCH 1/4] feat: working farcaster client with neynar --- .env.example | 5 + agent/package.json | 1 + packages/client-farcaster/package.json | 19 + packages/client-farcaster/pnpm-lock.yaml | 1478 +++++++++++++++++ packages/client-farcaster/src/actions.ts | 58 + packages/client-farcaster/src/client.ts | 216 +++ packages/client-farcaster/src/index.ts | 69 + packages/client-farcaster/src/interactions.ts | 236 +++ packages/client-farcaster/src/memory.ts | 111 ++ packages/client-farcaster/src/post.ts | 173 ++ packages/client-farcaster/src/prompts.ts | 79 + packages/client-farcaster/src/types.ts | 39 + packages/client-farcaster/src/utils.ts | 137 ++ packages/client-farcaster/tsconfig.json | 10 + packages/client-farcaster/tsup.config.ts | 20 + packages/core/src/types.ts | 1 + pnpm-lock.yaml | 377 ++++- scripts/build.sh | 1 + scripts/dev.sh | 1 + scripts/docker.sh | 1 + 20 files changed, 3031 insertions(+), 1 deletion(-) create mode 100644 packages/client-farcaster/package.json create mode 100644 packages/client-farcaster/pnpm-lock.yaml create mode 100644 packages/client-farcaster/src/actions.ts create mode 100644 packages/client-farcaster/src/client.ts create mode 100644 packages/client-farcaster/src/index.ts create mode 100644 packages/client-farcaster/src/interactions.ts create mode 100644 packages/client-farcaster/src/memory.ts create mode 100644 packages/client-farcaster/src/post.ts create mode 100644 packages/client-farcaster/src/prompts.ts create mode 100644 packages/client-farcaster/src/types.ts create mode 100644 packages/client-farcaster/src/utils.ts create mode 100644 packages/client-farcaster/tsconfig.json create mode 100644 packages/client-farcaster/tsup.config.ts diff --git a/.env.example b/.env.example index f16f77609fe..abd3fd03dd6 100644 --- a/.env.example +++ b/.env.example @@ -93,3 +93,8 @@ STARKNET_RPC_URL= # Coinbase Commerce COINBASE_COMMERCE_KEY= + +# Farcaster Neynar Configuration +FARCASTER_FID= +FARCASTER_NEYNAR_SIGNER_UUID= +FARCASTER_NEYNAR_API_KEY= \ No newline at end of file diff --git a/agent/package.json b/agent/package.json index 2eb890ba8a5..412a073e961 100644 --- a/agent/package.json +++ b/agent/package.json @@ -17,6 +17,7 @@ "@ai16z/client-auto": "workspace:*", "@ai16z/client-direct": "workspace:*", "@ai16z/client-discord": "workspace:*", + "@ai16z/client-farcaster": "workspace:*", "@ai16z/client-telegram": "workspace:*", "@ai16z/client-twitter": "workspace:*", "@ai16z/eliza": "workspace:*", diff --git a/packages/client-farcaster/package.json b/packages/client-farcaster/package.json new file mode 100644 index 00000000000..cd7a1ba8252 --- /dev/null +++ b/packages/client-farcaster/package.json @@ -0,0 +1,19 @@ +{ + "name": "@ai16z/client-farcaster", + "version": "0.0.1", + "main": "dist/index.js", + "type": "module", + "types": "dist/index.d.ts", + "dependencies": { + "@ai16z/eliza": "workspace:*", + "@neynar/nodejs-sdk": "^2.0.3", + "viem": "^2.21.47" + }, + "devDependencies": { + "tsup": "^8.3.5" + }, + "scripts": { + "build": "tsup --format esm --dts", + "dev": "tsup --watch" + } +} diff --git a/packages/client-farcaster/pnpm-lock.yaml b/packages/client-farcaster/pnpm-lock.yaml new file mode 100644 index 00000000000..3ed01a948fa --- /dev/null +++ b/packages/client-farcaster/pnpm-lock.yaml @@ -0,0 +1,1478 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@farcaster/hub-nodejs': + specifier: ^0.12.7 + version: 0.12.7(zod@3.23.8) + viem: + specifier: ^2.21.47 + version: 2.21.49(zod@3.23.8) + devDependencies: + tsup: + specifier: ^8.3.5 + version: 8.3.5(postcss@8.4.49)(yaml@2.6.1) + +packages: + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@faker-js/faker@7.6.0': + resolution: {integrity: sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==} + engines: {node: '>=14.0.0', npm: '>=6.0.0'} + + '@farcaster/core@0.15.6': + resolution: {integrity: sha512-Vxq2JhqdZYEMjH4PIwPXQkalY46S4Mol2oCSHUafXenDx6WSoQJqF/4an4KyxGQbmA7Cf8+hl6zuNzkkHXEUyQ==} + + '@farcaster/hub-nodejs@0.12.7': + resolution: {integrity: sha512-05zXNqnHRBSbOkHl0KDh6l60nHK5MiKFky0JBGbdOZXdkFCk4FIiHv9AGLxjFXr/FxA3jSTHUJfvRRe5TonjRw==} + + '@grpc/grpc-js@1.11.3': + resolution: {integrity: sha512-i9UraDzFHMR+Iz/MhFLljT+fCpgxZ3O6CxwGJ8YuNYHJItIHUzKJpW2LvoFZNnGPwqc9iWy9RAucxV0JoR9aUQ==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.7.13': + resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} + engines: {node: '>=6'} + hasBin: true + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + + '@noble/curves@1.6.0': + resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.7.0': + resolution: {integrity: sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.5.0': + resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.6.0': + resolution: {integrity: sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==} + engines: {node: ^14.21.3 || >=16} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@rollup/rollup-android-arm-eabi@4.27.4': + resolution: {integrity: sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.27.4': + resolution: {integrity: sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.27.4': + resolution: {integrity: sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.27.4': + resolution: {integrity: sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.27.4': + resolution: {integrity: sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.27.4': + resolution: {integrity: sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.27.4': + resolution: {integrity: sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.27.4': + resolution: {integrity: sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.27.4': + resolution: {integrity: sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.27.4': + resolution: {integrity: sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.4': + resolution: {integrity: sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.27.4': + resolution: {integrity: sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.27.4': + resolution: {integrity: sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.27.4': + resolution: {integrity: sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.27.4': + resolution: {integrity: sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.27.4': + resolution: {integrity: sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.27.4': + resolution: {integrity: sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.27.4': + resolution: {integrity: sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==} + cpu: [x64] + os: [win32] + + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + + '@scure/bip32@1.5.0': + resolution: {integrity: sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==} + + '@scure/bip39@1.4.0': + resolution: {integrity: sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/node@22.9.3': + resolution: {integrity: sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==} + + abitype@1.0.6: + resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + + bundle-require@5.0.0: + resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + neverthrow@6.2.2: + resolution: {integrity: sha512-POR1FACqdK9jH0S2kRPzaZEvzT11wsOxLW520PQV/+vKi9dQe+hXq19EiOvYx7lSRaF5VB9lYGsPInynrnN05w==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + ox@0.1.2: + resolution: {integrity: sha512-ak/8K0Rtphg9vnRJlbOdaX9R7cmxD2MiSthjWGaQdMk3D7hrAlDoM+6Lxn7hN52Za3vrXfZ7enfke/5WjolDww==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + protobufjs@7.4.0: + resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} + engines: {node: '>=12.0.0'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + rollup@4.27.4: + resolution: {integrity: sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsup@8.3.5: + resolution: {integrity: sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + viem@2.21.49: + resolution: {integrity: sha512-NNItYfTv4+yGE5DDKc+S/g2S7KeJn047GwgEYG60FAJlK0FzwuP6lQKSeQ8k7Y4VasfuKPqiT+XiilcCtTRiDQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + webauthn-p256@0.0.10: + resolution: {integrity: sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.6.1: + resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + +snapshots: + + '@adraffy/ens-normalize@1.11.0': {} + + '@esbuild/aix-ppc64@0.24.0': + optional: true + + '@esbuild/android-arm64@0.24.0': + optional: true + + '@esbuild/android-arm@0.24.0': + optional: true + + '@esbuild/android-x64@0.24.0': + optional: true + + '@esbuild/darwin-arm64@0.24.0': + optional: true + + '@esbuild/darwin-x64@0.24.0': + optional: true + + '@esbuild/freebsd-arm64@0.24.0': + optional: true + + '@esbuild/freebsd-x64@0.24.0': + optional: true + + '@esbuild/linux-arm64@0.24.0': + optional: true + + '@esbuild/linux-arm@0.24.0': + optional: true + + '@esbuild/linux-ia32@0.24.0': + optional: true + + '@esbuild/linux-loong64@0.24.0': + optional: true + + '@esbuild/linux-mips64el@0.24.0': + optional: true + + '@esbuild/linux-ppc64@0.24.0': + optional: true + + '@esbuild/linux-riscv64@0.24.0': + optional: true + + '@esbuild/linux-s390x@0.24.0': + optional: true + + '@esbuild/linux-x64@0.24.0': + optional: true + + '@esbuild/netbsd-x64@0.24.0': + optional: true + + '@esbuild/openbsd-arm64@0.24.0': + optional: true + + '@esbuild/openbsd-x64@0.24.0': + optional: true + + '@esbuild/sunos-x64@0.24.0': + optional: true + + '@esbuild/win32-arm64@0.24.0': + optional: true + + '@esbuild/win32-ia32@0.24.0': + optional: true + + '@esbuild/win32-x64@0.24.0': + optional: true + + '@faker-js/faker@7.6.0': {} + + '@farcaster/core@0.15.6(zod@3.23.8)': + dependencies: + '@faker-js/faker': 7.6.0 + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.0 + bs58: 5.0.0 + neverthrow: 6.2.2 + viem: 2.21.49(zod@3.23.8) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@farcaster/hub-nodejs@0.12.7(zod@3.23.8)': + dependencies: + '@farcaster/core': 0.15.6(zod@3.23.8) + '@grpc/grpc-js': 1.11.3 + '@noble/hashes': 1.6.0 + neverthrow: 6.2.2 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@grpc/grpc-js@1.11.3': + dependencies: + '@grpc/proto-loader': 0.7.13 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.7.13': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.2.3 + protobufjs: 7.4.0 + yargs: 17.7.2 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@js-sdsl/ordered-map@4.4.2': {} + + '@noble/curves@1.6.0': + dependencies: + '@noble/hashes': 1.5.0 + + '@noble/curves@1.7.0': + dependencies: + '@noble/hashes': 1.6.0 + + '@noble/hashes@1.5.0': {} + + '@noble/hashes@1.6.0': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@rollup/rollup-android-arm-eabi@4.27.4': + optional: true + + '@rollup/rollup-android-arm64@4.27.4': + optional: true + + '@rollup/rollup-darwin-arm64@4.27.4': + optional: true + + '@rollup/rollup-darwin-x64@4.27.4': + optional: true + + '@rollup/rollup-freebsd-arm64@4.27.4': + optional: true + + '@rollup/rollup-freebsd-x64@4.27.4': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.27.4': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.27.4': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.27.4': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.27.4': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.4': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.27.4': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.27.4': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.27.4': + optional: true + + '@rollup/rollup-linux-x64-musl@4.27.4': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.27.4': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.27.4': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.27.4': + optional: true + + '@scure/base@1.1.9': {} + + '@scure/bip32@1.5.0': + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.4.0': + dependencies: + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + + '@types/estree@1.0.6': {} + + '@types/node@22.9.3': + dependencies: + undici-types: 6.19.8 + + abitype@1.0.6(zod@3.23.8): + optionalDependencies: + zod: 3.23.8 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + balanced-match@1.0.2: {} + + base-x@4.0.0: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + bs58@5.0.0: + dependencies: + base-x: 4.0.0 + + bundle-require@5.0.0(esbuild@0.24.0): + dependencies: + esbuild: 0.24.0 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@4.1.1: {} + + consola@3.2.3: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + esbuild@0.24.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + + escalade@3.2.0: {} + + eventemitter3@5.0.1: {} + + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + get-caller-file@2.0.5: {} + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + is-fullwidth-code-point@3.0.0: {} + + isexe@2.0.0: {} + + isows@1.0.6(ws@8.18.0): + dependencies: + ws: 8.18.0 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + joycon@3.1.1: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lodash.camelcase@4.3.0: {} + + lodash.sortby@4.7.0: {} + + long@5.2.3: {} + + lru-cache@10.4.3: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.7: + optional: true + + neverthrow@6.2.2: {} + + object-assign@4.1.1: {} + + ox@0.1.2(zod@3.23.8): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/bip32': 1.5.0 + '@scure/bip39': 1.4.0 + abitype: 1.0.6(zod@3.23.8) + eventemitter3: 5.0.1 + transitivePeerDependencies: + - zod + + package-json-from-dist@1.0.1: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + picocolors@1.1.1: {} + + picomatch@4.0.2: {} + + pirates@4.0.6: {} + + postcss-load-config@6.0.1(postcss@8.4.49)(yaml@2.6.1): + dependencies: + lilconfig: 3.1.2 + optionalDependencies: + postcss: 8.4.49 + yaml: 2.6.1 + + postcss@8.4.49: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + optional: true + + protobufjs@7.4.0: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 22.9.3 + long: 5.2.3 + + punycode@2.3.1: {} + + readdirp@4.0.2: {} + + require-directory@2.1.1: {} + + resolve-from@5.0.0: {} + + rollup@4.27.4: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.27.4 + '@rollup/rollup-android-arm64': 4.27.4 + '@rollup/rollup-darwin-arm64': 4.27.4 + '@rollup/rollup-darwin-x64': 4.27.4 + '@rollup/rollup-freebsd-arm64': 4.27.4 + '@rollup/rollup-freebsd-x64': 4.27.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.27.4 + '@rollup/rollup-linux-arm-musleabihf': 4.27.4 + '@rollup/rollup-linux-arm64-gnu': 4.27.4 + '@rollup/rollup-linux-arm64-musl': 4.27.4 + '@rollup/rollup-linux-powerpc64le-gnu': 4.27.4 + '@rollup/rollup-linux-riscv64-gnu': 4.27.4 + '@rollup/rollup-linux-s390x-gnu': 4.27.4 + '@rollup/rollup-linux-x64-gnu': 4.27.4 + '@rollup/rollup-linux-x64-musl': 4.27.4 + '@rollup/rollup-win32-arm64-msvc': 4.27.4 + '@rollup/rollup-win32-ia32-msvc': 4.27.4 + '@rollup/rollup-win32-x64-msvc': 4.27.4 + fsevents: 2.3.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + source-map-js@1.2.1: + optional: true + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyexec@0.3.1: {} + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + + tsup@8.3.5(postcss@8.4.49)(yaml@2.6.1): + dependencies: + bundle-require: 5.0.0(esbuild@0.24.0) + cac: 6.7.14 + chokidar: 4.0.1 + consola: 3.2.3 + debug: 4.3.7 + esbuild: 0.24.0 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(postcss@8.4.49)(yaml@2.6.1) + resolve-from: 5.0.0 + rollup: 4.27.4 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.1 + tinyglobby: 0.2.10 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.4.49 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + undici-types@6.19.8: {} + + viem@2.21.49(zod@3.23.8): + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/bip32': 1.5.0 + '@scure/bip39': 1.4.0 + abitype: 1.0.6(zod@3.23.8) + isows: 1.0.6(ws@8.18.0) + ox: 0.1.2(zod@3.23.8) + webauthn-p256: 0.0.10 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + webauthn-p256@0.0.10: + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + + webidl-conversions@4.0.2: {} + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + ws@8.18.0: {} + + y18n@5.0.8: {} + + yaml@2.6.1: + optional: true + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + zod@3.23.8: + optional: true diff --git a/packages/client-farcaster/src/actions.ts b/packages/client-farcaster/src/actions.ts new file mode 100644 index 00000000000..ab8cfe686a3 --- /dev/null +++ b/packages/client-farcaster/src/actions.ts @@ -0,0 +1,58 @@ +import type { FarcasterClient } from "./client"; +import type { Content, IAgentRuntime, Memory, UUID } from "@ai16z/eliza"; +import type { Cast, CastId, NeynarCastResponse, Profile } from "./types"; +import { createCastMemory } from "./memory"; +import { splitPostContent } from "./utils"; + +export async function sendCast({ + client, + runtime, + content, + roomId, + inReplyTo, + profile, +}: { + profile: Profile; + client: FarcasterClient; + runtime: IAgentRuntime; + content: Content; + roomId: UUID; + signerUuid: string; + inReplyTo?: CastId; +}): Promise<{ memory: Memory; cast: Cast }[]> { + const chunks = splitPostContent(content.text); + const sent: Cast[] = []; + let parentCastId = inReplyTo; + + for (const chunk of chunks) { + const neynarCast = await client.publishCast(chunk, parentCastId); + + if (neynarCast) { + const cast: Cast = { + hash: neynarCast.hash, + authorFid: neynarCast.authorFid, + text: neynarCast.text, + profile, + inReplyTo: parentCastId, + timestamp: new Date(), + }; + + sent.push(cast!); + + parentCastId = { + fid: neynarCast?.authorFid!, + hash: neynarCast?.hash!, + }; + } + } + + return sent.map((cast) => ({ + cast, + memory: createCastMemory({ + roomId, + agentId: runtime.agentId, + userId: runtime.agentId, + cast, + }), + })); +} diff --git a/packages/client-farcaster/src/client.ts b/packages/client-farcaster/src/client.ts new file mode 100644 index 00000000000..63461869d4d --- /dev/null +++ b/packages/client-farcaster/src/client.ts @@ -0,0 +1,216 @@ +import { IAgentRuntime } from "@ai16z/eliza"; +import { NeynarAPIClient, isApiErrorResponse } from "@neynar/nodejs-sdk"; +import { NeynarCastResponse, Cast, Profile, FidRequest, CastId } from "./types"; + +export class FarcasterClient { + runtime: IAgentRuntime; + neynar: NeynarAPIClient; + signerUuid: string; + cache: Map; + lastInteractionTimestamp: Date; + + constructor(opts: { + runtime: IAgentRuntime; + url: string; + ssl: boolean; + neynar: NeynarAPIClient; + signerUuid: string; + cache: Map; + }) { + this.cache = opts.cache; + this.runtime = opts.runtime; + this.neynar = opts.neynar; + this.signerUuid = opts.signerUuid; + this.lastInteractionTimestamp = new Date(); + } + + async loadCastFromNeynarResponse(neynarResponse: any): Promise { + const profile = await this.getProfile(neynarResponse.author.fid); + return { + hash: neynarResponse.hash, + authorFid: neynarResponse.author.fid, + text: neynarResponse.text, + profile, + ...(neynarResponse.parent_hash + ? { + inReplyTo: { + hash: neynarResponse.parent_hash, + fid: neynarResponse.parent_author.fid, + }, + } + : {}), + timestamp: new Date(neynarResponse.timestamp), + }; + } + + async publishCast( + cast: string, + parentCastId: CastId | undefined, + retryTimes?: number + ): Promise { + try { + const result = await this.neynar.publishCast({ + signerUuid: this.signerUuid, + text: cast, + parent: parentCastId?.hash, + }); + if (result.success) { + return { + hash: result.cast.hash, + authorFid: result.cast.author.fid, + text: result.cast.text, + }; + } + } catch (err) { + if (isApiErrorResponse(err)) { + console.log(err.response.data); + throw err.response.data; + } else { + throw err; + console.log(err); + } + } + } + + async getCast(castHash: string): Promise { + if (this.cache.has(`farcaster/cast/${castHash}`)) { + return this.cache.get(`farcaster/cast/${castHash}`); + } + + const response = await this.neynar.lookupCastByHashOrWarpcastUrl({ + identifier: castHash, + type: "hash", + }); + const cast = { + hash: response.cast.hash, + //parentHash: cast.parent_hash, + authorFid: response.cast.author.fid, + text: response.cast.text, + profile: { + fid: response.cast.author.fid, + name: response.cast.author.display_name || "anon", + username: response.cast.author.username, + }, + timestamp: new Date(response.cast.timestamp), + }; + + this.cache.set(`farcaster/cast/${castHash}`, cast); + + return cast; + } + + async getCastsByFid(request: FidRequest): Promise { + const timeline: Cast[] = []; + + const response = await this.neynar.fetchCastsForUser({ + fid: request.fid, + limit: request.pageSize, + }); + //console.log(response); + response.casts.map((cast) => { + this.cache.set(`farcaster/cast/${cast.hash}`, cast); + timeline.push({ + hash: cast.hash, + //parentHash: cast.parent_hash, + authorFid: cast.author.fid, + text: cast.text, + profile: { + fid: cast.author.fid, + name: cast.author.display_name || "anon", + username: cast.author.username, + }, + timestamp: new Date(cast.timestamp), + }); + }); + + return timeline; + } + + async getMentions(request: FidRequest): Promise { + const neynarMentionsResponse = await this.neynar.fetchAllNotifications({ + fid: request.fid, + type: ["mentions", "replies"], + }); + const mentions: Cast[] = []; + + neynarMentionsResponse.notifications.map((notification) => { + const cast = { + hash: notification.cast!.hash, + authorFid: notification.cast!.author.fid, + text: notification.cast!.text, + profile: { + fid: notification.cast!.author.fid, + name: notification.cast!.author.display_name || "anon", + username: notification.cast!.author.username, + }, + timestamp: new Date(notification.cast!.timestamp), + }; + mentions.push(cast); + this.cache.set(`farcaster/cast/${cast.hash}`, cast); + }); + + return mentions; + } + + async getProfile(fid: number): Promise { + if (this.cache.has(`farcaster/profile/${fid}`)) { + return this.cache.get(`farcaster/profile/${fid}`) as Profile; + } + + const result = await this.neynar.fetchBulkUsers({ fids: [fid] }); + //console.log(result) + if (!result.users || result.users.length < 1) { + console.log("getUserDataByFid ERROR"); + + throw "getUserDataByFid ERROR"; + } + + const neynarUserProfile = result.users[0]; + + const profile: Profile = { + fid, + name: "", + username: "", + }; + + const userDataBodyType = { + 1: "pfp", + 2: "name", + 3: "bio", + 5: "url", + 6: "username", + // 7: "location", + // 8: "twitter", + // 9: "github", + } as const; + + profile.name = neynarUserProfile.display_name!; + profile.username = neynarUserProfile.username; + profile.bio = neynarUserProfile.profile.bio.text; + profile.pfp = neynarUserProfile.pfp_url; + + this.cache.set(`farcaster/profile/${fid}`, profile); + + return profile; + } + + async getTimeline(request: FidRequest): Promise<{ + timeline: Cast[]; + nextPageToken?: Uint8Array | undefined; + }> { + const timeline: Cast[] = []; + + const results = await this.getCastsByFid(request); + + for (const cast of results) { + this.cache.set(`farcaster/cast/${cast.hash}`, cast); + timeline.push(cast); + } + + return { + timeline, + //TODO implement out paging + //nextPageToken: results.nextPageToken, + }; + } +} diff --git a/packages/client-farcaster/src/index.ts b/packages/client-farcaster/src/index.ts new file mode 100644 index 00000000000..30f9bf292db --- /dev/null +++ b/packages/client-farcaster/src/index.ts @@ -0,0 +1,69 @@ +import { Client, IAgentRuntime } from "@ai16z/eliza"; +import { FarcasterClient } from "./client"; +import { FarcasterPostManager } from "./post"; +import { FarcasterInteractionManager } from "./interactions"; +import { Configuration, NeynarAPIClient } from "@neynar/nodejs-sdk"; + +export class FarcasterAgentClient implements Client { + client: FarcasterClient; + posts: FarcasterPostManager; + interactions: FarcasterInteractionManager; + + private signerUuid: string; + + constructor( + public runtime: IAgentRuntime, + client?: FarcasterClient + ) { + const cache = new Map(); + + this.signerUuid = runtime.getSetting("FARCASTER_NEYNAR_SIGNER_UUID")!; + + const neynarConfig = new Configuration({ + apiKey: runtime.getSetting("FARCASTER_NEYNAR_API_KEY")!, // Replace with your Neynar API Key. + }); + + const neynarClient = new NeynarAPIClient(neynarConfig); + + this.client = + client ?? + new FarcasterClient({ + runtime, + ssl: true, + url: + runtime.getSetting("FARCASTER_HUB_URL") ?? + "hub.pinata.cloud", + neynar: neynarClient, + signerUuid: this.signerUuid, + cache, + }); + + console.log("%c✔ SUCCESS", "color: #8565cb; font-weight: bold;"); + console.log( + "%c Farcaster Neynar client initialized.", + "color: #8565cb;" + ); + + this.posts = new FarcasterPostManager( + this.client, + this.runtime, + this.signerUuid, + cache + ); + + this.interactions = new FarcasterInteractionManager( + this.client, + this.runtime, + this.signerUuid, + cache + ); + } + + async start() { + await Promise.all([this.posts.start(), this.interactions.start()]); + } + + async stop() { + await Promise.all([this.posts.stop(), this.interactions.stop()]); + } +} diff --git a/packages/client-farcaster/src/interactions.ts b/packages/client-farcaster/src/interactions.ts new file mode 100644 index 00000000000..95b2ee36684 --- /dev/null +++ b/packages/client-farcaster/src/interactions.ts @@ -0,0 +1,236 @@ +import { + composeContext, + generateMessageResponse, + generateShouldRespond, + Memory, + ModelClass, + stringToUuid, + type IAgentRuntime, +} from "@ai16z/eliza"; +import type { FarcasterClient } from "./client"; +import { toHex } from "viem"; +import { buildConversationThread, createCastMemory } from "./memory"; +import { Cast, Profile } from "./types"; +import { + formatCast, + formatTimeline, + messageHandlerTemplate, + shouldRespondTemplate, +} from "./prompts"; +import { castUuid } from "./utils"; +import { sendCast } from "./actions"; + +export class FarcasterInteractionManager { + private timeout: NodeJS.Timeout | undefined; + constructor( + public client: FarcasterClient, + public runtime: IAgentRuntime, + private signerUuid: string, + public cache: Map + ) {} + + public async start() { + const handleInteractionsLoop = async () => { + try { + await this.handleInteractions(); + } catch (error) { + console.error(error); + return; + } + + this.timeout = setTimeout( + handleInteractionsLoop, + (Math.floor(Math.random() * (5 - 2 + 1)) + 2) * 60 * 1000 + ); // Random interval between 2-5 minutes + }; + + handleInteractionsLoop(); + } + + public async stop() { + if (this.timeout) clearTimeout(this.timeout); + } + + private async handleInteractions() { + const agentFid = Number(this.runtime.getSetting("FARCASTER_FID")); + + const mentions = await this.client.getMentions({ + fid: agentFid, + pageSize: 10, + }); + + const agent = await this.client.getProfile(agentFid); + console.log( + `[Farcaster Neynar Client] Found ${mentions.length} mentions.` + ); + for (const mention of mentions) { + const messageHash = toHex(mention.hash); + const conversationId = `${messageHash}-${this.runtime.agentId}`; + const roomId = stringToUuid(conversationId); + const userId = stringToUuid(mention.authorFid.toString()); + + await this.runtime.ensureConnection( + userId, + roomId, + mention.profile.username, + mention.profile.name, + "farcaster" + ); + + await buildConversationThread({ + client: this.client, + runtime: this.runtime, + cast: mention, + }); + + const memory: Memory = { + content: { text: mention.text }, + agentId: this.runtime.agentId, + userId, + roomId, + }; + + await this.handleCast({ + agent, + cast: mention, + memory, + }); + } + + this.client.lastInteractionTimestamp = new Date(); + } + + private async handleCast({ + agent, + cast, + memory, + }: { + agent: Profile; + cast: Cast; + memory: Memory; + }) { + if (cast.profile.fid === agent.fid) { + console.log("skipping cast from bot itself", cast.hash); + return; + } + + if (!memory.content.text) { + console.log("skipping cast with no text", cast.hash); + return { text: "", action: "IGNORE" }; + } + + const currentPost = formatCast(cast); + + const { timeline } = await this.client.getTimeline({ + fid: agent.fid, + pageSize: 10, + }); + + const formattedTimeline = formatTimeline( + this.runtime.character, + timeline + ); + + const state = await this.runtime.composeState(memory, { + farcasterUsername: agent.username, + timeline: formattedTimeline, + currentPost, + }); + + const shouldRespondContext = composeContext({ + state, + template: + /*this.runtime.character.templates + ?.farcasterShouldRespondTemplate ||*/ + this.runtime.character?.templates?.shouldRespondTemplate || + shouldRespondTemplate, + }); + + const memoryId = castUuid({ + agentId: this.runtime.agentId, + hash: cast.hash, + }); + + const castMemory = + await this.runtime.messageManager.getMemoryById(memoryId); + + if (!castMemory) { + await this.runtime.messageManager.createMemory( + createCastMemory({ + agentId: this.runtime.agentId, + roomId: memory.roomId, + userId: memory.userId, + cast, + }) + ); + } + + const shouldRespond = await generateShouldRespond({ + runtime: this.runtime, + context: shouldRespondContext, + modelClass: ModelClass.SMALL, + }); + + if (!shouldRespond) { + console.log("Not responding to message"); + return { text: "", action: "IGNORE" }; + } + + const context = composeContext({ + state, + template: + /*this.runtime.character.templates + ?.farcasterMessageHandlerTemplate ??*/ + this.runtime.character?.templates?.messageHandlerTemplate ?? + messageHandlerTemplate, + }); + + const response = await generateMessageResponse({ + runtime: this.runtime, + context, + modelClass: ModelClass.SMALL, + }); + + response.inReplyTo = memoryId; + + if (!response.text) return; + + if (cast.timestamp < this.client.lastInteractionTimestamp) { + console.log(`Cast ${cast.hash} was sent before startup. Skipping.`); + return; + } + + try { + console.log(`Replying to cast ${cast.hash}.`); + + const results = await sendCast({ + runtime: this.runtime, + client: this.client, + signerUuid: this.signerUuid, + profile: cast.profile, + content: response, + roomId: memory.roomId, + inReplyTo: { + fid: cast.authorFid, + hash: cast.hash, + }, + }); + + const newState = await this.runtime.updateRecentMessageState(state); + + for (const { memory } of results) { + await this.runtime.messageManager.createMemory(memory); + } + + await this.runtime.evaluate(memory, newState); + + await this.runtime.processActions( + memory, + results.map((result) => result.memory), + newState + ); + } catch (error) { + console.error(`Error sending response cast: ${error}`); + } + } +} diff --git a/packages/client-farcaster/src/memory.ts b/packages/client-farcaster/src/memory.ts new file mode 100644 index 00000000000..e53ac76a65d --- /dev/null +++ b/packages/client-farcaster/src/memory.ts @@ -0,0 +1,111 @@ +import { + elizaLogger, + embeddingZeroVector, + IAgentRuntime, + stringToUuid, + type Memory, + type UUID, +} from "@ai16z/eliza"; +import type { Cast } from "./types"; +import { toHex } from "viem"; +import { castUuid } from "./utils"; +import { FarcasterClient } from "./client"; + +//TODO refactor for neynar responses +export function createCastMemory({ + roomId, + agentId, + userId, + cast, +}: { + roomId: UUID; + agentId: UUID; + userId: UUID; + cast: Cast; +}): Memory { + const inReplyTo = cast.inReplyTo + ? castUuid({ + hash: toHex(cast.inReplyTo.hash), + agentId, + }) + : undefined; + + return { + id: castUuid({ + hash: cast.hash, + agentId, + }), + agentId, + userId, + content: { + text: cast.text, + source: "farcaster", + url: "", + inReplyTo, + hash: cast.hash, + }, + roomId, + embedding: embeddingZeroVector, + }; +} + +export async function buildConversationThread({ + cast, + runtime, + client, +}: { + cast: Cast; + runtime: IAgentRuntime; + client: FarcasterClient; +}): Promise { + const thread: Cast[] = []; + const visited: Set = new Set(); + + async function processThread(currentCast: Cast) { + if (visited.has(cast.hash)) { + return; + } + + visited.add(cast.hash); + + const roomId = castUuid({ + hash: currentCast.hash, + agentId: runtime.agentId, + }); + + // Check if the current cast has already been saved + const memory = await runtime.messageManager.getMemoryById(roomId); + + if (!memory) { + elizaLogger.log("Creating memory for cast", cast.hash); + + const userId = stringToUuid(cast.profile.username); + + await runtime.ensureConnection( + userId, + roomId, + currentCast.profile.username, + currentCast.profile.name, + "farcaster" + ); + + await runtime.messageManager.createMemory( + createCastMemory({ + roomId, + agentId: runtime.agentId, + userId, + cast: currentCast, + }) + ); + } + + thread.unshift(currentCast); + + if (currentCast.inReplyTo) { + const parentCast = await client.getCast(currentCast.inReplyTo.hash); + await processThread(parentCast); + } + } + + await processThread(cast); +} diff --git a/packages/client-farcaster/src/post.ts b/packages/client-farcaster/src/post.ts new file mode 100644 index 00000000000..92d866661c8 --- /dev/null +++ b/packages/client-farcaster/src/post.ts @@ -0,0 +1,173 @@ +import { + composeContext, + generateText, + IAgentRuntime, + ModelClass, + stringToUuid, +} from "@ai16z/eliza"; +import { FarcasterClient } from "./client"; +import { formatTimeline, postTemplate } from "./prompts"; +import { castUuid } from "./utils"; +import { createCastMemory } from "./memory"; +import { sendCast } from "./actions"; + +export class FarcasterPostManager { + private timeout: NodeJS.Timeout | undefined; + + constructor( + public client: FarcasterClient, + public runtime: IAgentRuntime, + private signerUuid: string, + public cache: Map + ) {} + + public async start() { + const generateNewCastLoop = async () => { + try { + await this.generateNewCast(); + } catch (error) { + console.error(error); + return; + } + + this.timeout = setTimeout( + generateNewCastLoop, + (Math.floor(Math.random() * (4 - 1 + 1)) + 1) * 60 * 60 * 1000 + ); // Random interval between 1 and 4 hours + }; + + generateNewCastLoop(); + } + + public async stop() { + if (this.timeout) clearTimeout(this.timeout); + } + + private async generateNewCast() { + console.log( + "%c [Farcaster Neynar Client] Generating new cast...", + "color: #8565cb;" + ); + try { + const fid = Number(this.runtime.getSetting("FARCASTER_FID")!); + // const farcasterUserName = + // this.runtime.getSetting("FARCASTER_USERNAME")!; + + const profile = await this.client.getProfile(fid); + await this.runtime.ensureUserExists( + this.runtime.agentId, + profile.username, + this.runtime.character.name, + "farcaster" + ); + + const { timeline } = await this.client.getTimeline({ + fid, + pageSize: 10, + }); + + this.cache.set("farcaster/timeline", timeline); + + const formattedHomeTimeline = formatTimeline( + this.runtime.character, + timeline + ); + + const generateRoomId = stringToUuid("farcaster_generate_room"); + + const state = await this.runtime.composeState( + { + roomId: generateRoomId, + userId: this.runtime.agentId, + agentId: this.runtime.agentId, + content: { text: "", action: "" }, + }, + { + farcasterUserName: profile.username, + timeline: formattedHomeTimeline, + } + ); + + // Generate new tweet + const context = composeContext({ + state, + template: + //this.runtime.character.templates?.farcasterPostTemplate || + postTemplate, + }); + + const newContent = await generateText({ + runtime: this.runtime, + context, + modelClass: ModelClass.SMALL, + }); + + const slice = newContent.replaceAll(/\\n/g, "\n").trim(); + + const contentLength = 240; + + let content = slice.slice(0, contentLength); + // if its bigger than 280, delete the last line + if (content.length > 280) { + content = content.slice(0, content.lastIndexOf("\n")); + } + + if (content.length > contentLength) { + // slice at the last period + content = content.slice(0, content.lastIndexOf(".")); + } + + // if it's still too long, get the period before the last period + if (content.length > contentLength) { + content = content.slice(0, content.lastIndexOf(".")); + } + + try { + // TODO: handle all the casts? + const [{ cast }] = await sendCast({ + client: this.client, + runtime: this.runtime, + //: this.signer, + signerUuid: this.signerUuid, + roomId: generateRoomId, + content: { text: content }, + profile, + }); + + const roomId = castUuid({ + agentId: this.runtime.agentId, + hash: cast.hash, + }); + + await this.runtime.ensureRoomExists(roomId); + + await this.runtime.ensureParticipantInRoom( + this.runtime.agentId, + roomId + ); + + console.log( + "%c✔ SUCCESS", + "color: #8565cb; font-weight: bold;" + ); + console.log( + `%c [Farcaster Neynar Client] Published cast ${cast.hash}`, + "color: #8565cb;" + ); + + await this.runtime.messageManager.createMemory( + createCastMemory({ + roomId, + userId: this.runtime.agentId, + agentId: this.runtime.agentId, + cast, + }) + ); + } catch (error) { + console.error("Error sending cast:", error); + } + } catch (error) { + console.error("Error generating new cast:", error); + } + } +} diff --git a/packages/client-farcaster/src/prompts.ts b/packages/client-farcaster/src/prompts.ts new file mode 100644 index 00000000000..bbd30a87678 --- /dev/null +++ b/packages/client-farcaster/src/prompts.ts @@ -0,0 +1,79 @@ +import { + Character, + messageCompletionFooter, + shouldRespondFooter, +} from "@ai16z/eliza"; +import type { Cast } from "./types"; + +export const formatCast = (cast: Cast) => { + return `ID: ${cast.hash} + From: ${cast.profile.name} (@${cast.profile.username})${cast.profile.username})${cast.inReplyTo ? `\nIn reply to: ${cast.inReplyTo.fid}` : ""} +Text: ${cast.text}`; +}; + +export const formatTimeline = ( + character: Character, + timeline: Cast[] +) => `# ${character.name}'s Home Timeline +${timeline.map(formatCast).join("\n")} +`; + +export const headerTemplate = ` +{{timeline}} + +# Knowledge +{{knowledge}} + +About {{agentName}} (@{{farcasterUserName}}): +{{bio}} +{{lore}} +{{postDirections}} + +{{providers}} + +{{recentPosts}} + +{{characterPostExamples}}`; + +export const postTemplate = + headerTemplate + + ` +# Task: Generate a post in the voice and style of {{agentName}}, aka @{{farcasterUserName}} +Write a single sentence post that is {{adjective}} about {{topic}} (without mentioning {{topic}} directly), from the perspective of {{agentName}}. +Try to write something totally different than previous posts. Do not add commentary or ackwowledge this request, just write the post. + +Your response should not contain any questions. Brief, concise statements only. No emojis. Use \\n\\n (double spaces) between statements.`; + +export const messageHandlerTemplate = + headerTemplate + + ` +Recent interactions between {{agentName}} and other users: +{{recentPostInteractions}} + +# Task: Generate a post in the voice, style and perspective of {{agentName}} (@{{twitterUserName}}): +{{currentPost}}` + + messageCompletionFooter; + +export const shouldRespondTemplate = + // + `# INSTRUCTIONS: Determine if {{agentName}} (@{{twitterUserName}}) should respond to the message and participate in the conversation. Do not comment. Just respond with "true" or "false". + +Response options are RESPOND, IGNORE and STOP. + +{{agentName}} should respond to messages that are directed at them, or participate in conversations that are interesting or relevant to their background, IGNORE messages that are irrelevant to them, and should STOP if the conversation is concluded. + +{{agentName}} is in a room with other users and wants to be conversational, but not annoying. +{{agentName}} should RESPOND to messages that are directed at them, or participate in conversations that are interesting or relevant to their background. +If a message is not interesting or relevant, {{agentName}} should IGNORE. +Unless directly RESPONDing to a user, {{agentName}} should IGNORE messages that are very short or do not contain much information. +If a user asks {{agentName}} to stop talking, {{agentName}} should STOP. +If {{agentName}} concludes a conversation and isn't part of the conversation anymore, {{agentName}} should STOP. + +{{recentPosts}} + +IMPORTANT: {{agentName}} (aka @{{twitterUserName}}) is particularly sensitive about being annoying, so if there is any doubt, it is better to IGNORE than to RESPOND. + +{{currentPost}} + +# INSTRUCTIONS: Respond with [RESPOND] if {{agentName}} should respond, or [IGNORE] if {{agentName}} should not respond to the last message and [STOP] if {{agentName}} should stop participating in the conversation. +` + shouldRespondFooter; diff --git a/packages/client-farcaster/src/types.ts b/packages/client-farcaster/src/types.ts new file mode 100644 index 00000000000..929216d138b --- /dev/null +++ b/packages/client-farcaster/src/types.ts @@ -0,0 +1,39 @@ +export type Profile = { + fid: number; + name: string; + username: string; + pfp?: string; + bio?: string; + url?: string; + // location?: string; + // twitter?: string; + // github?: string; +}; + +export type NeynarCastResponse = { + hash: string; + authorFid: number; + text: string; +}; + +export type Cast = { + hash: string; + authorFid: number; + text: string; + profile: Profile; + inReplyTo?: { + hash: string; + fid: number; + }; + timestamp: Date; +}; + +export type CastId = { + hash: string; + fid: number; +}; + +export type FidRequest = { + fid: number; + pageSize: number; +}; diff --git a/packages/client-farcaster/src/utils.ts b/packages/client-farcaster/src/utils.ts new file mode 100644 index 00000000000..1b74e9566fd --- /dev/null +++ b/packages/client-farcaster/src/utils.ts @@ -0,0 +1,137 @@ +import { stringToUuid } from "@ai16z/eliza"; +import type { Hex } from "viem"; + +const MAX_CAST_LENGTH = 280; // Updated to Twitter's current character limit + +export function castId({ hash, agentId }: { hash: string; agentId: string }) { + return `${hash}-${agentId}`; +} + +export function castUuid(props: { hash: string; agentId: string }) { + return stringToUuid(castId(props)); +} + +export function splitPostContent( + content: string, + maxLength: number = MAX_CAST_LENGTH +): string[] { + const paragraphs = content.split("\n\n").map((p) => p.trim()); + const posts: string[] = []; + let currentTweet = ""; + + for (const paragraph of paragraphs) { + if (!paragraph) continue; + + if ((currentTweet + "\n\n" + paragraph).trim().length <= maxLength) { + if (currentTweet) { + currentTweet += "\n\n" + paragraph; + } else { + currentTweet = paragraph; + } + } else { + if (currentTweet) { + posts.push(currentTweet.trim()); + } + if (paragraph.length <= maxLength) { + currentTweet = paragraph; + } else { + // Split long paragraph into smaller chunks + const chunks = splitParagraph(paragraph, maxLength); + posts.push(...chunks.slice(0, -1)); + currentTweet = chunks[chunks.length - 1]; + } + } + } + + if (currentTweet) { + posts.push(currentTweet.trim()); + } + + return posts; +} + +export function splitParagraph(paragraph: string, maxLength: number): string[] { + const sentences = paragraph.match(/[^\.!\?]+[\.!\?]+|[^\.!\?]+$/g) || [ + paragraph, + ]; + const chunks: string[] = []; + let currentChunk = ""; + + for (const sentence of sentences) { + if ((currentChunk + " " + sentence).trim().length <= maxLength) { + if (currentChunk) { + currentChunk += " " + sentence; + } else { + currentChunk = sentence; + } + } else { + if (currentChunk) { + chunks.push(currentChunk.trim()); + } + if (sentence.length <= maxLength) { + currentChunk = sentence; + } else { + // Split long sentence into smaller pieces + const words = sentence.split(" "); + currentChunk = ""; + for (const word of words) { + if ( + (currentChunk + " " + word).trim().length <= maxLength + ) { + if (currentChunk) { + currentChunk += " " + word; + } else { + currentChunk = word; + } + } else { + if (currentChunk) { + chunks.push(currentChunk.trim()); + } + currentChunk = word; + } + } + } + } + } + + if (currentChunk) { + chunks.push(currentChunk.trim()); + } + + return chunks; +} + +export function populateMentions( + text: string, + userIds: number[], + positions: number[], + userMap: Record +) { + // Validate input arrays have same length + if (userIds.length !== positions.length) { + throw new Error( + "User IDs and positions arrays must have the same length" + ); + } + + // Create array of mention objects with position and user info + const mentions = userIds + .map((userId, index) => ({ + position: positions[index], + userId, + displayName: userMap[userId]!, + })) + .sort((a, b) => b.position - a.position); // Sort in reverse order to prevent position shifting + + // Create the resulting string by inserting mentions + let result = text; + mentions.forEach((mention) => { + const mentionText = `@${mention.displayName}`; + result = + result.slice(0, mention.position) + + mentionText + + result.slice(mention.position); + }); + + return result; +} diff --git a/packages/client-farcaster/tsconfig.json b/packages/client-farcaster/tsconfig.json new file mode 100644 index 00000000000..42d468a1356 --- /dev/null +++ b/packages/client-farcaster/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "outDir": "dist", + "rootDir": "./src", + "strict": true + }, + "include": ["src"] +} diff --git a/packages/client-farcaster/tsup.config.ts b/packages/client-farcaster/tsup.config.ts new file mode 100644 index 00000000000..e42bf4efeae --- /dev/null +++ b/packages/client-farcaster/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + // Add other modules you want to externalize + ], +}); diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 4864c526e8c..337a7cf0083 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -583,6 +583,7 @@ export enum Clients { DIRECT = "direct", TWITTER = "twitter", TELEGRAM = "telegram", + FARCASTER = "farcaster", } /** * Configuration for an agent character diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7be6c75d4ea..bf1ae61fd5c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,6 +75,9 @@ importers: '@ai16z/client-discord': specifier: workspace:* version: link:../packages/client-discord + '@ai16z/client-farcaster': + specifier: workspace:* + version: link:../packages/client-farcaster '@ai16z/client-telegram': specifier: workspace:* version: link:../packages/client-telegram @@ -533,6 +536,22 @@ importers: specifier: ^8.3.5 version: 8.3.5(@swc/core@1.9.3(@swc/helpers@0.5.15))(jiti@2.4.0)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) + packages/client-farcaster: + dependencies: + '@ai16z/eliza': + specifier: workspace:* + version: link:../core + '@neynar/nodejs-sdk': + specifier: ^2.0.3 + version: 2.0.3(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) + viem: + specifier: ^2.21.47 + version: 2.21.50(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) + devDependencies: + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.9.3(@swc/helpers@0.5.15))(jiti@2.4.0)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) + packages/client-github: dependencies: '@ai16z/eliza': @@ -3882,6 +3901,10 @@ packages: resolution: {integrity: sha512-DPnl5lPX4v49eVxEbJnAizrpMdMTBz1qykZrAbBul9rfgk531v8oAt+Pm6O/rpAleRombNM7FJb5rYGzBJatOQ==} engines: {node: '>=18.0.0'} + '@lukeed/csprng@1.1.0': + resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + engines: {node: '>=8'} + '@mapbox/node-pre-gyp@1.0.11': resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} hasBin: true @@ -3905,12 +3928,57 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + '@nestjs/axios@3.1.1': + resolution: {integrity: sha512-ySoxrzqX80P1q6LKLKGcgyBd2utg4gbC+4FsJNpXYvILorMlxss/ECNogD9EXLCE4JS5exVFD5ez0nK5hXcNTQ==} + peerDependencies: + '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + axios: ^1.3.1 + rxjs: ^6.0.0 || ^7.0.0 + + '@nestjs/common@10.4.6': + resolution: {integrity: sha512-KkezkZvU9poWaNq4L+lNvx+386hpOxPJkfXBBeSMrcqBOx8kVr36TGN2uYkF4Ta4zNu1KbCjmZbc0rhHSg296g==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + + '@nestjs/core@10.4.6': + resolution: {integrity: sha512-zXVPxCNRfO6gAy0yvEDjUxE/8gfZICJFpsl2lZAUH31bPb6m+tXuhUq2mVCTEltyMYQ+DYtRe+fEYM2v152N1g==} + peerDependencies: + '@nestjs/common': ^10.0.0 + '@nestjs/microservices': ^10.0.0 + '@nestjs/platform-express': ^10.0.0 + '@nestjs/websockets': ^10.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + '@nestjs/websockets': + optional: true + + '@neynar/nodejs-sdk@2.0.3': + resolution: {integrity: sha512-v+nXUuCOjXRLm05PQArbpONfDeN2v7rM5AlDpzqN6wy7ms35zAtCO43IVkJN/bvECDJxo4yPvnCTMECrWnqILA==} + engines: {node: '>=19.9.0'} + '@noble/curves@1.2.0': resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} '@noble/curves@1.3.0': resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + '@noble/curves@1.6.0': + resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} + engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.7.0': resolution: {integrity: sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==} engines: {node: ^14.21.3 || >=16} @@ -4067,6 +4135,11 @@ packages: resolution: {integrity: sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==} engines: {node: ^16.14.0 || >=18.0.0} + '@nuxtjs/opencollective@0.3.2': + resolution: {integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + '@nx/devkit@20.1.3': resolution: {integrity: sha512-+bNCRNSHKS7SS4Q2xI/p4hhd4mIibIbeF+hpF3TLO5wxyXbrYGSdhCVK5SwclwWUN/KhcKQjOrVGW5CKAm7HAw==} peerDependencies: @@ -4351,6 +4424,11 @@ packages: resolution: {integrity: sha512-I5YPUtfWidh+OzyrlDahJsUpkpGK0kCTmDRbuqGmlCUzOtxdEkX3R4d6Cd08ijQYwkVXQJanPdbKuZBeV2NMaA==} engines: {node: '>= 18'} + '@openapitools/openapi-generator-cli@2.15.3': + resolution: {integrity: sha512-2UBnsDlMt36thhdXxisbA1qReVtbCaw+NCvXoslRXlaJBL4qkAmZUhNeDLNu3LCbwA2PASMWhJSqeLwgwMCitw==} + engines: {node: '>=16'} + hasBin: true + '@opendocsg/pdf2md@0.1.31': resolution: {integrity: sha512-Pinl9WSL3P7pMeIdriQCYuBymspbGwt+Wic9ocoIGSYQuxccRC6fMzhRXAgO//MqwTSbgPiKHzYFE2v7Azd9gw==} hasBin: true @@ -4804,6 +4882,12 @@ packages: '@scure/base@1.1.9': resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + '@scure/bip32@1.5.0': + resolution: {integrity: sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==} + + '@scure/bip39@1.4.0': + resolution: {integrity: sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==} + '@scure/starknet@1.0.0': resolution: {integrity: sha512-o5J57zY0f+2IL/mq8+AYJJ4Xpc1fOtDhr+mFQKbHnYFmm3WQrC+8zj2HEgxak1a+x86mhmBC1Kq305KUpVf0wg==} @@ -6100,6 +6184,17 @@ packages: resolution: {integrity: sha512-JlqiAl9CPvTm5kKG0QXmVCWNWoC/XyRMOeT77cQlbxXWllgjf6SqUmaNqFon72C2o5OSZids+5FvLdsw6dvWaw==} hasBin: true + abitype@1.0.6: + resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -7072,6 +7167,9 @@ packages: compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + compare-versions@4.1.4: + resolution: {integrity: sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==} + compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -7095,6 +7193,11 @@ packages: resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} engines: {'0': node >= 6.0} + concurrently@6.5.1: + resolution: {integrity: sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==} + engines: {node: '>=10.0.0'} + hasBin: true + concurrently@9.1.0: resolution: {integrity: sha512-VxkzwMAn4LP7WyMnJNbHN5mKV9L2IbyDjpzemKr99sXNR3GqRNMMHdm7prV1ws9wg7ETj6WUkNOigZVsptwbgg==} engines: {node: '>=18'} @@ -7114,6 +7217,9 @@ packages: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} engines: {node: '>=0.8'} + consola@2.15.3: + resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} + consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} @@ -7121,6 +7227,10 @@ packages: console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + console.table@0.10.0: + resolution: {integrity: sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==} + engines: {node: '> 0.10'} + consolidated-events@2.0.2: resolution: {integrity: sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ==} @@ -7628,6 +7738,10 @@ packages: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dateformat@3.0.3: resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} @@ -7959,6 +8073,9 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + easy-table@1.1.0: + resolution: {integrity: sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==} + ecc-jsbn@0.1.2: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} @@ -8438,6 +8555,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} @@ -9607,6 +9727,11 @@ packages: peerDependencies: ws: '*' + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} @@ -9634,6 +9759,10 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} + iterare@1.2.1: + resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} + engines: {node: '>=6'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -11283,6 +11412,14 @@ packages: otpauth@9.3.5: resolution: {integrity: sha512-jQyqOuQExeIl4YIiOUz4TdEcamgAgPX6UYeeS9Iit4lkvs7bwHb0JNDqchGRccbRfvWHV6oRwH36tOsVmc+7hQ==} + ox@0.1.2: + resolution: {integrity: sha512-ak/8K0Rtphg9vnRJlbOdaX9R7cmxD2MiSthjWGaQdMk3D7hrAlDoM+6Lxn7hN52Za3vrXfZ7enfke/5WjolDww==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -12498,6 +12635,10 @@ packages: resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} engines: {node: '>= 14'} + proxy-agent@6.4.0: + resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} + engines: {node: '>= 14'} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -12819,6 +12960,9 @@ packages: redeyed@2.1.1: resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + reflect-metadata@0.1.13: + resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + regenerate-unicode-properties@10.2.0: resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} @@ -13059,6 +13203,10 @@ packages: rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} @@ -13370,6 +13518,9 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spawn-command@0.0.2: + resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} + spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} @@ -14011,6 +14162,9 @@ packages: tslib@2.8.0: resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tslog@4.9.3: resolution: {integrity: sha512-oDWuGVONxhVEBtschLf2cs/Jy8i7h1T+CpdkTNWQgdAF7DhRo2G8vMCgILKe7ojdEkLhICWgI1LYSSKaJsRgcw==} engines: {node: '>=16'} @@ -14139,6 +14293,10 @@ packages: engines: {node: '>=0.8.0'} hasBin: true + uid@2.0.2: + resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} + engines: {node: '>=8'} + unbuild@2.0.0: resolution: {integrity: sha512-JWCUYx3Oxdzvw2J9kTAp+DKE8df/BnH/JTSj6JyA4SH40ECdFu7FoJJcrm8G92B7TjofQ6GZGjJs50TRxoH6Wg==} hasBin: true @@ -14397,6 +14555,14 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + viem@2.21.50: + resolution: {integrity: sha512-WHB8NmkaForODuSALb0Ai3E296aEigzYSE+pzB9Y0cTNJeiZT8rpkdxxUFYfjwFMnPkz2tivqrSpuw3hO5TH6w==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + vite-node@2.1.5: resolution: {integrity: sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==} engines: {node: ^18.0.0 || >=20.0.0} @@ -14544,6 +14710,9 @@ packages: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} + webauthn-p256@0.0.10: + resolution: {integrity: sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -18871,6 +19040,8 @@ snapshots: - supports-color - typescript + '@lukeed/csprng@1.1.0': {} + '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': dependencies: detect-libc: 2.0.3 @@ -18935,6 +19106,53 @@ snapshots: '@emnapi/runtime': 1.3.1 '@tybys/wasm-util': 0.9.0 + '@nestjs/axios@3.1.1(@nestjs/common@10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1))(axios@1.7.7)(rxjs@7.8.1)': + dependencies: + '@nestjs/common': 10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1) + axios: 1.7.7(debug@4.3.7) + rxjs: 7.8.1 + + '@nestjs/common@10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1)': + dependencies: + iterare: 1.2.1 + reflect-metadata: 0.1.13 + rxjs: 7.8.1 + tslib: 2.7.0 + uid: 2.0.2 + + '@nestjs/core@10.4.6(@nestjs/common@10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1))(encoding@0.1.13)(reflect-metadata@0.1.13)(rxjs@7.8.1)': + dependencies: + '@nestjs/common': 10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nuxtjs/opencollective': 0.3.2(encoding@0.1.13) + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 3.3.0 + reflect-metadata: 0.1.13 + rxjs: 7.8.1 + tslib: 2.7.0 + uid: 2.0.2 + transitivePeerDependencies: + - encoding + + '@neynar/nodejs-sdk@2.0.3(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8)': + dependencies: + '@openapitools/openapi-generator-cli': 2.15.3(encoding@0.1.13) + semver: 7.6.3 + viem: 2.21.50(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) + transitivePeerDependencies: + - '@nestjs/microservices' + - '@nestjs/platform-express' + - '@nestjs/websockets' + - bufferutil + - class-transformer + - class-validator + - debug + - encoding + - supports-color + - typescript + - utf-8-validate + - zod + '@noble/curves@1.2.0': dependencies: '@noble/hashes': 1.3.2 @@ -18943,6 +19161,10 @@ snapshots: dependencies: '@noble/hashes': 1.3.3 + '@noble/curves@1.6.0': + dependencies: + '@noble/hashes': 1.5.0 + '@noble/curves@1.7.0': dependencies: '@noble/hashes': 1.6.0 @@ -19130,6 +19352,14 @@ snapshots: - bluebird - supports-color + '@nuxtjs/opencollective@0.3.2(encoding@0.1.13)': + dependencies: + chalk: 4.1.2 + consola: 2.15.3 + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + '@nx/devkit@20.1.3(nx@20.1.3(@swc/core@1.9.3(@swc/helpers@0.5.15)))': dependencies: ejs: 3.1.10 @@ -19403,7 +19633,7 @@ snapshots: '@octokit/request-error': 3.0.3 '@octokit/types': 9.3.2 is-plain-object: 5.0.0 - node-fetch: 2.6.7(encoding@0.1.13) + node-fetch: 2.7.0(encoding@0.1.13) universal-user-agent: 6.0.1 transitivePeerDependencies: - encoding @@ -19464,6 +19694,36 @@ snapshots: '@octokit/request-error': 6.1.5 '@octokit/webhooks-methods': 5.1.0 + '@openapitools/openapi-generator-cli@2.15.3(encoding@0.1.13)': + dependencies: + '@nestjs/axios': 3.1.1(@nestjs/common@10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1))(axios@1.7.7)(rxjs@7.8.1) + '@nestjs/common': 10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/core': 10.4.6(@nestjs/common@10.4.6(reflect-metadata@0.1.13)(rxjs@7.8.1))(encoding@0.1.13)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nuxtjs/opencollective': 0.3.2(encoding@0.1.13) + axios: 1.7.7(debug@4.3.7) + chalk: 4.1.2 + commander: 8.3.0 + compare-versions: 4.1.4 + concurrently: 6.5.1 + console.table: 0.10.0 + fs-extra: 10.1.0 + glob: 9.3.5 + inquirer: 8.2.6 + lodash: 4.17.21 + proxy-agent: 6.4.0 + reflect-metadata: 0.1.13 + rxjs: 7.8.1 + tslib: 2.8.1 + transitivePeerDependencies: + - '@nestjs/microservices' + - '@nestjs/platform-express' + - '@nestjs/websockets' + - class-transformer + - class-validator + - debug + - encoding + - supports-color + '@opendocsg/pdf2md@0.1.31(encoding@0.1.13)': dependencies: enumify: 1.0.4 @@ -19899,6 +20159,17 @@ snapshots: '@scure/base@1.1.9': {} + '@scure/bip32@1.5.0': + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.4.0': + dependencies: + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + '@scure/starknet@1.0.0': dependencies: '@noble/curves': 1.3.0 @@ -21628,6 +21899,11 @@ snapshots: fs-extra: 10.1.0 yargs: 17.7.2 + abitype@1.0.6(typescript@5.6.3)(zod@3.23.8): + optionalDependencies: + typescript: 5.6.3 + zod: 3.23.8 + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -22751,6 +23027,8 @@ snapshots: array-ify: 1.0.0 dot-prop: 5.3.0 + compare-versions@4.1.4: {} + compressible@2.0.18: dependencies: mime-db: 1.53.0 @@ -22789,6 +23067,17 @@ snapshots: readable-stream: 3.6.2 typedarray: 0.0.6 + concurrently@6.5.1: + dependencies: + chalk: 4.1.2 + date-fns: 2.30.0 + lodash: 4.17.21 + rxjs: 6.6.7 + spawn-command: 0.0.2 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 16.2.0 + concurrently@9.1.0: dependencies: chalk: 4.1.2 @@ -22816,10 +23105,16 @@ snapshots: connect-history-api-fallback@2.0.0: {} + consola@2.15.3: {} + consola@3.2.3: {} console-control-strings@1.1.0: {} + console.table@0.10.0: + dependencies: + easy-table: 1.1.0 + consolidated-events@2.0.2: {} content-disposition@0.5.2: {} @@ -23429,6 +23724,10 @@ snapshots: whatwg-mimetype: 4.0.0 whatwg-url: 14.0.0 + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.26.0 + dateformat@3.0.3: {} dayjs@1.11.13: {} @@ -23743,6 +24042,10 @@ snapshots: eastasianwidth@0.2.0: {} + easy-table@1.1.0: + optionalDependencies: + wcwidth: 1.0.1 + ecc-jsbn@0.1.2: dependencies: jsbn: 0.1.1 @@ -24383,6 +24686,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-safe-stringify@2.1.1: {} + fast-stable-stringify@1.0.0: {} fast-uri@3.0.3: {} @@ -25715,6 +26020,10 @@ snapshots: dependencies: ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + isows@1.0.6(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + isstream@0.1.2: {} istanbul-lib-coverage@3.2.2: {} @@ -25758,6 +26067,8 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + iterare@1.2.1: {} + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -28165,6 +28476,20 @@ snapshots: dependencies: '@noble/hashes': 1.5.0 + ox@0.1.2(typescript@5.6.3)(zod@3.23.8): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.0 + '@scure/bip32': 1.5.0 + '@scure/bip39': 1.4.0 + abitype: 1.0.6(typescript@5.6.3)(zod@3.23.8) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - zod + p-cancelable@3.0.0: {} p-finally@1.0.0: {} @@ -29425,6 +29750,19 @@ snapshots: transitivePeerDependencies: - supports-color + proxy-agent@6.4.0: + dependencies: + agent-base: 7.1.1 + debug: 4.3.7(supports-color@5.5.0) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.2 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.4 + transitivePeerDependencies: + - supports-color + proxy-from-env@1.1.0: {} psl@1.13.0: @@ -29865,6 +30203,8 @@ snapshots: dependencies: esprima: 4.0.1 + reflect-metadata@0.1.13: {} + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -30193,6 +30533,10 @@ snapshots: rw@1.3.3: {} + rxjs@6.6.7: + dependencies: + tslib: 1.9.3 + rxjs@7.8.1: dependencies: tslib: 2.8.0 @@ -30589,6 +30933,8 @@ snapshots: space-separated-tokens@2.0.2: {} + spawn-command@0.0.2: {} + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 @@ -31276,6 +31622,8 @@ snapshots: tslib@2.8.0: {} + tslib@2.8.1: {} + tslog@4.9.3: {} tsup@8.3.5(@swc/core@1.9.3(@swc/helpers@0.5.15))(jiti@2.4.0)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1): @@ -31393,6 +31741,10 @@ snapshots: uglify-js@3.19.3: optional: true + uid@2.0.2: + dependencies: + '@lukeed/csprng': 1.1.0 + unbuild@2.0.0(typescript@5.6.3): dependencies: '@rollup/plugin-alias': 5.1.1(rollup@3.29.5) @@ -31692,6 +32044,24 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 + viem@2.21.50(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/bip32': 1.5.0 + '@scure/bip39': 1.4.0 + abitype: 1.0.6(typescript@5.6.3)(zod@3.23.8) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + ox: 0.1.2(typescript@5.6.3)(zod@3.23.8) + webauthn-p256: 0.0.10 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vite-node@2.1.5(@types/node@22.8.4)(terser@5.36.0): dependencies: cac: 6.7.14 @@ -31849,6 +32219,11 @@ snapshots: web-streams-polyfill@4.0.0-beta.3: {} + webauthn-p256@0.0.10: + dependencies: + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.0 + webidl-conversions@3.0.1: {} webidl-conversions@4.0.2: {} diff --git a/scripts/build.sh b/scripts/build.sh index 9fbbe5f2fb0..e60e868cb27 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -31,6 +31,7 @@ PACKAGES=( "client-auto" "client-direct" "client-discord" + "client-farcaster" "client-telegram" "client-twitter" "plugin-node" diff --git a/scripts/dev.sh b/scripts/dev.sh index e65a3eb5869..b93af22b421 100644 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -3,6 +3,7 @@ npx concurrently --raw \ "pnpm --dir packages/core dev -- $*" \ "pnpm --dir packages/client-telegram dev -- $*" \ "pnpm --dir packages/client-discord dev -- $*" \ + "pnpm --dir packages/client-farcaster dev -- $*" \ "pnpm --dir packages/client-twitter dev -- $*" \ "pnpm --dir packages/client-direct dev -- $*" \ "pnpm --dir packages/plugin-bootstrap dev -- $*" \ diff --git a/scripts/docker.sh b/scripts/docker.sh index 66800ca5e63..45dc5500648 100755 --- a/scripts/docker.sh +++ b/scripts/docker.sh @@ -37,6 +37,7 @@ case "$1" in "client-auto" "client-direct" "client-discord" + "client-farcaster" "client-telegram" "client-twitter" "core" From 24f9876dd90aec3c75c4548330063ecb02bbae6e Mon Sep 17 00:00:00 2001 From: sayangel Date: Mon, 2 Dec 2024 19:59:30 -0800 Subject: [PATCH 2/4] fix: package version --- packages/client-farcaster/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client-farcaster/package.json b/packages/client-farcaster/package.json index faa80a8212b..b33af8f7dd7 100644 --- a/packages/client-farcaster/package.json +++ b/packages/client-farcaster/package.json @@ -1,6 +1,6 @@ { "name": "@ai16z/client-farcaster", - "version": "0.2.1-alpha.3", + "version": "0.1.5-alpha.1", "main": "dist/index.js", "type": "module", "types": "dist/index.d.ts", From 023545e5ae96442bddc030d9a32e21b08954b332 Mon Sep 17 00:00:00 2001 From: sayangel Date: Mon, 2 Dec 2024 20:54:51 -0800 Subject: [PATCH 3/4] fix memory --- packages/client-farcaster/src/client.ts | 16 ++++++++++++ packages/client-farcaster/src/interactions.ts | 25 ++++++++++++------- packages/client-farcaster/src/memory.ts | 12 ++++----- packages/client-farcaster/src/prompts.ts | 7 ++++-- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/packages/client-farcaster/src/client.ts b/packages/client-farcaster/src/client.ts index 611d7d8e7cf..9aa780dc4f1 100644 --- a/packages/client-farcaster/src/client.ts +++ b/packages/client-farcaster/src/client.ts @@ -91,6 +91,14 @@ export class FarcasterClient { name: response.cast.author.display_name || "anon", username: response.cast.author.username, }, + ...(response.cast.parent_hash + ? { + inReplyTo: { + hash: response.cast.parent_hash, + fid: response.cast.parent_author.fid, + }, + } + : {}), timestamp: new Date(response.cast.timestamp), }; @@ -143,6 +151,14 @@ export class FarcasterClient { name: notification.cast!.author.display_name || "anon", username: notification.cast!.author.username, }, + ...(notification.cast!.parent_hash + ? { + inReplyTo: { + hash: notification.cast!.parent_hash, + fid: notification.cast!.parent_author.fid, + }, + } + : {}), timestamp: new Date(notification.cast!.timestamp), }; mentions.push(cast); diff --git a/packages/client-farcaster/src/interactions.ts b/packages/client-farcaster/src/interactions.ts index 4ef3ac9b2a0..65c5c308aeb 100644 --- a/packages/client-farcaster/src/interactions.ts +++ b/packages/client-farcaster/src/interactions.ts @@ -60,15 +60,24 @@ export class FarcasterInteractionManager { }); const agent = await this.client.getProfile(agentFid); - console.log( - `[Farcaster Neynar Client] Found ${mentions.length} mentions.` - ); for (const mention of mentions) { const messageHash = toHex(mention.hash); const conversationId = `${messageHash}-${this.runtime.agentId}`; const roomId = stringToUuid(conversationId); const userId = stringToUuid(mention.authorFid.toString()); + const pastMemoryId = castUuid({ + agentId: this.runtime.agentId, + hash: mention.hash, + }); + + const pastMemory = + await this.runtime.messageManager.getMemoryById(pastMemoryId); + + if (pastMemory) { + continue; + } + await this.runtime.ensureConnection( userId, roomId, @@ -77,7 +86,7 @@ export class FarcasterInteractionManager { "farcaster" ); - await buildConversationThread({ + const thread = await buildConversationThread({ client: this.client, runtime: this.runtime, cast: mention, @@ -94,6 +103,7 @@ export class FarcasterInteractionManager { agent, cast: mention, memory, + thread }); } @@ -104,10 +114,12 @@ export class FarcasterInteractionManager { agent, cast, memory, + thread }: { agent: Profile; cast: Cast; memory: Memory; + thread: Cast[] }) { if (cast.profile.fid === agent.fid) { console.log("skipping cast from bot itself", cast.hash); @@ -194,11 +206,6 @@ export class FarcasterInteractionManager { if (!response.text) return; - if (cast.timestamp < this.client.lastInteractionTimestamp) { - console.log(`Cast ${cast.hash} was sent before startup. Skipping.`); - return; - } - try { console.log(`Replying to cast ${cast.hash}.`); diff --git a/packages/client-farcaster/src/memory.ts b/packages/client-farcaster/src/memory.ts index 520a37865ca..b3a8c862c96 100644 --- a/packages/client-farcaster/src/memory.ts +++ b/packages/client-farcaster/src/memory.ts @@ -54,16 +54,15 @@ export async function buildConversationThread({ cast: Cast; runtime: IAgentRuntime; client: FarcasterClient; -}): Promise { +}): Promise { const thread: Cast[] = []; const visited: Set = new Set(); - async function processThread(currentCast: Cast) { - if (visited.has(cast.hash)) { + if (visited.has(currentCast.hash)) { return; } - visited.add(cast.hash); + visited.add(currentCast.hash); const roomId = castUuid({ hash: currentCast.hash, @@ -74,9 +73,9 @@ export async function buildConversationThread({ const memory = await runtime.messageManager.getMemoryById(roomId); if (!memory) { - elizaLogger.log("Creating memory for cast", cast.hash); + elizaLogger.log("Creating memory for cast", currentCast.hash); - const userId = stringToUuid(cast.profile.username); + const userId = stringToUuid(currentCast.profile.username); await runtime.ensureConnection( userId, @@ -104,4 +103,5 @@ export async function buildConversationThread({ } await processThread(cast); + return thread; } diff --git a/packages/client-farcaster/src/prompts.ts b/packages/client-farcaster/src/prompts.ts index 6b39a3a94d0..b9e0326d729 100644 --- a/packages/client-farcaster/src/prompts.ts +++ b/packages/client-farcaster/src/prompts.ts @@ -24,7 +24,7 @@ export const headerTemplate = ` # Knowledge {{knowledge}} -About {{agentName}} (@{{farcasterUserName}}): +About {{agentName}} (@{{farcasterUsername}}): {{bio}} {{lore}} {{postDirections}} @@ -38,7 +38,7 @@ About {{agentName}} (@{{farcasterUserName}}): export const postTemplate = headerTemplate + ` -# Task: Generate a post in the voice and style of {{agentName}}, aka @{{farcasterUserName}} +# Task: Generate a post in the voice and style of {{agentName}}, aka @{{farcasterUsername}} Write a single sentence post that is {{adjective}} about {{topic}} (without mentioning {{topic}} directly), from the perspective of {{agentName}}. Try to write something totally different than previous posts. Do not add commentary or ackwowledge this request, just write the post. @@ -50,6 +50,9 @@ export const messageHandlerTemplate = Recent interactions between {{agentName}} and other users: {{recentPostInteractions}} +Thread of casts You Are Replying To: +{{formattedConversation}} + # Task: Generate a post in the voice, style and perspective of {{agentName}} (@{{twitterUserName}}): {{currentPost}}` + messageCompletionFooter; From 35477bb8b23ec719b330982bade1dfe2801f7584 Mon Sep 17 00:00:00 2001 From: sayangel Date: Mon, 2 Dec 2024 21:03:54 -0800 Subject: [PATCH 4/4] add farcaster client to agent --- agent/src/index.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/agent/src/index.ts b/agent/src/index.ts index c2174f2903f..34faceb9b78 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -5,6 +5,7 @@ import { DirectClientInterface } from "@ai16z/client-direct"; import { DiscordClientInterface } from "@ai16z/client-discord"; import { TelegramClientInterface } from "@ai16z/client-telegram"; import { TwitterClientInterface } from "@ai16z/client-twitter"; +import { FarcasterAgentClient } from "@ai16z/client-farcaster"; import { AgentRuntime, CacheManager, @@ -322,6 +323,12 @@ export async function initializeClients( clients.push(twitterClients); } + if (clientTypes.includes("farcaster")) { + const farcasterClients = new FarcasterAgentClient(runtime); + farcasterClients.start(); + clients.push(farcasterClients); + } + if (character.plugins?.length > 0) { for (const plugin of character.plugins) { if (plugin.clients) {