From 2263d5c72c51b6f830c9de88c07eec9e6ff1c93e Mon Sep 17 00:00:00 2001 From: Ai16Z Partners Date: Wed, 4 Dec 2024 21:20:11 -0800 Subject: [PATCH 1/3] push --- packages/client-whatsapp/package.json | 23 +++++++++++++++ packages/client-whatsapp/src/actions/index.ts | 0 packages/client-whatsapp/src/environment.ts | 21 ++++++++++++++ packages/client-whatsapp/src/index.ts | 28 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 packages/client-whatsapp/package.json create mode 100644 packages/client-whatsapp/src/actions/index.ts create mode 100644 packages/client-whatsapp/src/environment.ts create mode 100644 packages/client-whatsapp/src/index.ts diff --git a/packages/client-whatsapp/package.json b/packages/client-whatsapp/package.json new file mode 100644 index 0000000000..9a20800ecc --- /dev/null +++ b/packages/client-whatsapp/package.json @@ -0,0 +1,23 @@ +{ + "name": "@ai16z/client-whatsapp", + "version": "0.0.1", + "description": "WhatsApp client for Eliza", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "clean": "rimraf dist", + "test": "jest", + "lint": "eslint src --ext .ts" + }, + "dependencies": { + "@ai16z/eliza": "workspace:*" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "typescript": "^5.0.0", + "rimraf": "^5.0.0", + "jest": "^29.0.0", + "@types/jest": "^29.0.0" + } +} \ No newline at end of file diff --git a/packages/client-whatsapp/src/actions/index.ts b/packages/client-whatsapp/src/actions/index.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/client-whatsapp/src/environment.ts b/packages/client-whatsapp/src/environment.ts new file mode 100644 index 0000000000..3c04686026 --- /dev/null +++ b/packages/client-whatsapp/src/environment.ts @@ -0,0 +1,21 @@ +import { IAgentRuntime } from "@ai16z/eliza"; + +export async function validateWhatsAppConfig( + runtime: IAgentRuntime +): Promise { + const requiredSettings = [ + "WHATSAPP_API_TOKEN", + "WHATSAPP_PHONE_NUMBER_ID", + "WHATSAPP_APP_ID", + "WHATSAPP_APP_SECRET", + "WHATSAPP_WEBHOOK_VERIFY_TOKEN" + ]; + + for (const setting of requiredSettings) { + if (!runtime.getSetting(setting)) { + throw new Error( + `Missing required WhatsApp configuration: ${setting}` + ); + } + } +} \ No newline at end of file diff --git a/packages/client-whatsapp/src/index.ts b/packages/client-whatsapp/src/index.ts new file mode 100644 index 0000000000..f38b9dae85 --- /dev/null +++ b/packages/client-whatsapp/src/index.ts @@ -0,0 +1,28 @@ +import { elizaLogger } from "@ai16z/eliza"; +import { Client, IAgentRuntime } from "@ai16z/eliza"; +import { WhatsAppClient } from "./whatsappClient"; +import { validateWhatsAppConfig } from "../../../eliza/packages/client-whatsapp/src/environment"; + +export const WhatsAppClientInterface: Client = { + start: async (runtime: IAgentRuntime) => { + await validateWhatsAppConfig(runtime); + + const client = new WhatsAppClient( + runtime, + runtime.getSetting("WHATSAPP_API_TOKEN"), + runtime.getSetting("WHATSAPP_PHONE_NUMBER_ID") + ); + + await client.start(); + + elizaLogger.success( + `✅ WhatsApp client successfully started for character ${runtime.character.name}` + ); + return client; + }, + stop: async (runtime: IAgentRuntime) => { + elizaLogger.warn("WhatsApp client stopping..."); + }, +}; + +export default WhatsAppClientInterface; \ No newline at end of file From 83259753bd5ff905ec6ece7ab2717a8517b678eb Mon Sep 17 00:00:00 2001 From: Ai16Z Partners Date: Wed, 4 Dec 2024 22:06:09 -0800 Subject: [PATCH 2/3] make charity wallets an env variable rather than hardcoded wallets --- .env.example | 6 ++ packages/plugin-coinbase/src/utils.ts | 20 ++--- pnpm-lock.yaml | 109 ++++++++++++++++---------- 3 files changed, 79 insertions(+), 56 deletions(-) diff --git a/.env.example b/.env.example index 77c1d37c7a..58b33e0231 100644 --- a/.env.example +++ b/.env.example @@ -189,3 +189,9 @@ INTERNET_COMPUTER_ADDRESS= # Aptos APTOS_PRIVATE_KEY= # Aptos private key APTOS_NETWORK= # must be one of mainnet, testnet + +CHARITY_ADDRESS_BASE=0x1234567890123456789012345678901234567890 +CHARITY_ADDRESS_SOL=pWvDXKu6CpbKKvKQkZvDA66hgsTB6X2AgFxksYogHLV +CHARITY_ADDRESS_ETH=0x750EF1D7a0b4Ab1c97B7A623D7917CcEb5ea779C +CHARITY_ADDRESS_ARB=0x1234567890123456789012345678901234567890 +CHARITY_ADDRESS_POL=0x1234567890123456789012345678901234567890 diff --git a/packages/plugin-coinbase/src/utils.ts b/packages/plugin-coinbase/src/utils.ts index 799ee2c324..c48a0c76dc 100644 --- a/packages/plugin-coinbase/src/utils.ts +++ b/packages/plugin-coinbase/src/utils.ts @@ -380,22 +380,16 @@ export async function executeTransfer(wallet: Wallet, amount: number, sourceAsse /** * Gets the charity address based on the network. - * For now we are giving to the following charity, but will make this configurable in the future - * https://www.givedirectly.org/crypto/?_gl=1*va5e6k*_gcl_au*MTM1NDUzNTk5Mi4xNzMzMDczNjA3*_ga*OTIwMDMwNTMwLjE3MzMwNzM2MDg.*_ga_GV8XF9FJ16*MTczMzA3MzYwNy4xLjEuMTczMzA3MzYyMi40NS4wLjA. * @param {string} network - The network to use. + * @throws {Error} If charity address for the network is not configured */ export function getCharityAddress(network: string): string { - let charityAddress; - if (network === "base") { - charityAddress = "0x1234567890123456789012345678901234567890"; - } else if (network === "sol") { - charityAddress = "pWvDXKu6CpbKKvKQkZvDA66hgsTB6X2AgFxksYogHLV"; - } else if (network === "eth") { - charityAddress = "0x750EF1D7a0b4Ab1c97B7A623D7917CcEb5ea779C"; - } else if (network === "arb") { - charityAddress = "0x1234567890123456789012345678901234567890"; - } else if (network === "pol") { - charityAddress = "0x1234567890123456789012345678901234567890"; + const networkKey = `CHARITY_ADDRESS_${network.toUpperCase()}`; + const charityAddress = process.env[networkKey]; + + if (!charityAddress) { + throw new Error(`Charity address not configured for network ${network}. Please set ${networkKey} in your environment variables.`); } + return charityAddress; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5003fdbf76..3ec4dbf811 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -597,6 +597,28 @@ importers: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.0(@swc/helpers@0.5.15))(jiti@2.4.0)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) + packages/client-whatsapp: + dependencies: + '@ai16z/eliza': + specifier: workspace:* + version: link:../core + devDependencies: + '@types/jest': + specifier: ^29.0.0 + version: 29.5.14 + '@types/node': + specifier: ^20.0.0 + version: 20.17.9 + jest: + specifier: ^29.0.0 + version: 29.7.0(@types/node@20.17.9) + rimraf: + specifier: ^5.0.0 + version: 5.0.10 + typescript: + specifier: ^5.0.0 + version: 5.6.3 + packages/core: dependencies: '@ai-sdk/anthropic': @@ -19564,7 +19586,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -19577,14 +19599,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@swc/core@1.10.0(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.17.9)(ts-node@10.9.2(@swc/core@1.10.0(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -19609,7 +19631,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -19627,7 +19649,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.8.4 + '@types/node': 20.17.9 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -19649,7 +19671,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.8.4 + '@types/node': 20.17.9 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -19719,7 +19741,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -22107,13 +22129,13 @@ snapshots: '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/responselike': 1.0.3 '@types/chrome@0.0.278': @@ -22124,11 +22146,11 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.2 - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/connect@3.4.38': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/cors@2.8.17': dependencies: @@ -22281,14 +22303,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/qs': 6.9.17 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express-serve-static-core@5.0.2': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/qs': 6.9.17 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -22317,7 +22339,7 @@ snapshots: '@types/fluent-ffmpeg@2.1.27': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/geojson@7946.0.14': {} @@ -22328,7 +22350,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/gtag.js@0.0.12': {} @@ -22352,7 +22374,7 @@ snapshots: '@types/http-proxy@1.17.15': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/istanbul-lib-coverage@2.0.6': {} @@ -22373,7 +22395,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/mdast@4.0.4': dependencies: @@ -22395,12 +22417,12 @@ snapshots: '@types/node-fetch@2.6.12': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 form-data: 4.0.1 '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/node@10.17.60': {} @@ -22483,18 +22505,18 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/retry@0.12.0': {} '@types/sax@1.2.7': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/serve-index@1.9.4': dependencies: @@ -22503,12 +22525,12 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/send': 0.17.4 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/sql.js@1.4.9': dependencies: @@ -22519,7 +22541,7 @@ snapshots: '@types/tar@6.1.13': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 minipass: 4.2.8 '@types/trusted-types@2.0.7': @@ -22539,11 +22561,11 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/ws@8.5.13': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 '@types/yargs-parser@21.0.3': {} @@ -22553,7 +22575,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 optional: true '@typescript-eslint/eslint-plugin@8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.16.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.16.0(jiti@2.4.0))(typescript@5.6.3)': @@ -24533,7 +24555,7 @@ snapshots: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.17.9) + jest-config: 29.7.0(@types/node@20.17.9)(ts-node@10.9.2(@swc/core@1.10.0(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -25767,7 +25789,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 require-like: 0.1.2 event-emitter@0.3.5: @@ -27423,7 +27445,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -27452,7 +27474,7 @@ snapshots: create-jest: 29.7.0(@types/node@20.17.9) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.17.9) + jest-config: 29.7.0(@types/node@20.17.9)(ts-node@10.9.2(@swc/core@1.10.0(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -27500,7 +27522,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.17.9): + jest-config@29.7.0(@types/node@20.17.9)(ts-node@10.9.2(@swc/core@1.10.0(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -27526,6 +27548,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.17.9 + ts-node: 10.9.2(@swc/core@1.10.0(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -27585,7 +27608,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -27595,7 +27618,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 22.8.4 + '@types/node': 20.17.9 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -27634,7 +27657,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -27669,7 +27692,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -27697,7 +27720,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 chalk: 4.1.2 cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 @@ -27743,7 +27766,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -27762,7 +27785,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.8.4 + '@types/node': 20.17.9 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -27771,13 +27794,13 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 22.8.4 + '@types/node': 20.17.9 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -31178,7 +31201,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.8.4 + '@types/node': 20.17.9 long: 5.2.3 protocols@2.0.1: {} From 7ce827c1b6dc41721149d60f422c6cc2ae9a43fc Mon Sep 17 00:00:00 2001 From: Ai16Z Partners Date: Wed, 4 Dec 2024 22:08:49 -0800 Subject: [PATCH 3/3] default boolean --- .env.example | 2 ++ packages/plugin-coinbase/src/utils.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 58b33e0231..7b641de3f2 100644 --- a/.env.example +++ b/.env.example @@ -190,6 +190,8 @@ INTERNET_COMPUTER_ADDRESS= APTOS_PRIVATE_KEY= # Aptos private key APTOS_NETWORK= # must be one of mainnet, testnet +# Charity Configuration +IS_CHARITABLE=false # Set to true to enable charity donations CHARITY_ADDRESS_BASE=0x1234567890123456789012345678901234567890 CHARITY_ADDRESS_SOL=pWvDXKu6CpbKKvKQkZvDA66hgsTB6X2AgFxksYogHLV CHARITY_ADDRESS_ETH=0x750EF1D7a0b4Ab1c97B7A623D7917CcEb5ea779C diff --git a/packages/plugin-coinbase/src/utils.ts b/packages/plugin-coinbase/src/utils.ts index c48a0c76dc..f9f4752863 100644 --- a/packages/plugin-coinbase/src/utils.ts +++ b/packages/plugin-coinbase/src/utils.ts @@ -381,9 +381,17 @@ export async function executeTransfer(wallet: Wallet, amount: number, sourceAsse /** * Gets the charity address based on the network. * @param {string} network - The network to use. - * @throws {Error} If charity address for the network is not configured + * @param {boolean} isCharitable - Whether charity donations are enabled + * @throws {Error} If charity address for the network is not configured when charity is enabled */ -export function getCharityAddress(network: string): string { +export function getCharityAddress(network: string, isCharitable: boolean = false): string | null { + // Check both environment variable and passed parameter + const isCharityEnabled = process.env.IS_CHARITABLE === 'true' && isCharitable; + + if (!isCharityEnabled) { + return null; + } + const networkKey = `CHARITY_ADDRESS_${network.toUpperCase()}`; const charityAddress = process.env[networkKey];