├── .nvmrc ├── plugins ├── dpsnPlugin │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ ├── index.ts │ │ └── example.ts │ ├── coverage │ │ └── lcov-report │ │ │ ├── favicon.png │ │ │ ├── sort-arrow-sprite.png │ │ │ └── prettify.css │ ├── __test__ │ │ ├── __mocks__ │ │ │ └── dpsn-client.ts │ │ ├── setup.ts │ │ └── mocks │ │ │ ├── gameAgent.mock.ts │ │ │ └── dpsnClient.mock.ts │ ├── jest.config.js │ ├── package.json │ └── plugin_metadata.yml ├── attpsPlugin │ ├── .gitignore │ ├── .npmignore │ ├── .env.example │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── vite.config.ts │ ├── tsconfig.json │ ├── package.json │ └── README.md ├── rss3Plugin │ ├── .gitignore │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ └── example.ts │ └── package.json ├── s3Plugin │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ └── index.ts │ ├── .env.example │ ├── tsconfig.json │ └── package.json ├── adNetworkPlugin │ ├── .gitignore │ ├── .npmignore │ ├── src │ │ └── index.ts │ └── package.json ├── alchemyPlugin │ ├── .npmignore │ ├── .gitignore │ ├── .env.example │ ├── src │ │ ├── index.ts │ │ └── example.ts │ ├── tsconfig.json │ ├── package.json │ ├── plugin_metadata.yml │ └── README.md ├── alloraPlugin │ ├── .gitignore │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ └── example.ts │ ├── package.json │ └── tsconfig.json ├── discordPlugin │ ├── .npmignore │ ├── .gitignore │ ├── jest.config.js │ ├── src │ │ ├── index.ts │ │ └── example.ts │ └── package.json ├── ensoPlugin │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ ├── .env.example │ │ ├── constants.ts │ │ ├── utils.ts │ │ └── example.ts │ ├── .gitignore │ ├── tsconfig.json │ └── package.json ├── farcasterPlugin │ ├── .gitignore │ ├── .npmignore │ ├── src │ │ └── index.ts │ ├── package.json │ └── README.md ├── twitterPlugin │ ├── .gitignore │ ├── .npmignore │ ├── example │ │ ├── .env.example │ │ ├── media_file.png │ │ ├── virtuals-logo.png │ │ ├── package.json │ │ └── index.ts │ ├── src │ │ └── index.ts │ └── package.json ├── zytronPlugin │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ ├── utils.ts │ │ ├── index.ts │ │ ├── constants.ts │ │ ├── example.ts │ │ └── zytronWallet.ts │ ├── tsconfig.json │ └── package.json ├── evalEnginePlugin │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ ├── index.ts │ │ ├── evalEngine.ts │ │ └── tweet │ │ │ └── get-tweet.ts │ └── package.json ├── mindNetworkPlugin │ ├── .gitignore │ ├── .npmignore │ ├── src │ │ ├── cache.ts │ │ ├── index.ts │ │ └── example.ts │ ├── package.json │ ├── tsconfig.json │ └── README.md ├── onChainActionsPlugin │ ├── .gitignore │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ ├── .env.example │ │ ├── example.ts │ │ └── onChainActionsPlugin.ts │ ├── tsconfig.json │ └── package.json ├── telegramPlugin │ ├── .npmignore │ ├── .gitignore │ ├── jest.config.js │ ├── src │ │ └── index.ts │ └── package.json ├── acpPlugin │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ └── interface.ts │ ├── package.json │ └── example │ │ ├── agentic │ │ ├── .env.example │ │ └── env.ts │ │ └── reactive │ │ ├── .env.example │ │ └── env.ts ├── recallStoragePlugin │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ └── index.ts │ ├── .env.example │ ├── tsconfig.json │ └── package.json ├── d.a.t.aPlugin │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ ├── index.ts │ │ └── example.ts │ ├── .env.example │ ├── tsconfig.json │ └── package.json ├── tokenMetricsPlugin │ ├── tests │ │ └── test-scenarios │ │ │ └── market-analyst.ts │ ├── screenshots │ │ ├── Chat-1.png │ │ ├── Chat-2.png │ │ ├── Setup-1.png │ │ ├── Setup-2.png │ │ ├── Quantmetics Example.png │ │ └── Market Sentiment Example.png │ ├── env.example │ ├── tsconfig.json │ ├── plugin_metadata.yml │ ├── LICENSE │ └── src │ │ └── examples │ │ ├── example.hourlyTradingSignals.ts │ │ ├── example.priceData.ts │ │ ├── example.dailyOhlcv.ts │ │ ├── example.hourlyOhlcv.ts │ │ ├── example.tokenmetricsAi.ts │ │ ├── example.topMarketCap.ts │ │ ├── example.tradingSignals.ts │ │ ├── example.aiReports.ts │ │ ├── example.marketMetrics.ts │ │ ├── example.quantmetrics.ts │ │ ├── example.sentiments.ts │ │ ├── example.resistanceSupport.ts │ │ ├── example.correlation.ts │ │ ├── example.cryptoInvestors.ts │ │ ├── example.scenarioAnalysis.ts │ │ ├── example.tmGrade.ts │ │ ├── example.moonshotTokens.ts │ │ ├── example.technologyGrade.ts │ │ ├── example.fundamentalGrade.ts │ │ └── example.fullAgent.ts ├── deskExchangePlugin │ ├── jest.setup.js │ ├── .env.example │ ├── src │ │ ├── index.ts │ │ ├── utils.ts │ │ └── constants.ts │ ├── __test__ │ │ └── log.ts │ ├── jest.config.js │ ├── .gitignore │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── package.json │ ├── eslint.config.mjs │ └── README.md ├── stateofmikaPlugin │ ├── src │ │ └── index.ts │ ├── jest.config.js │ ├── .gitignore │ ├── tsconfig.json │ └── package.json ├── imageGenPlugin │ ├── src │ │ ├── index.ts │ │ └── example.ts │ └── package.json ├── echochambersPlugin │ ├── src │ │ ├── index.ts │ │ ├── types.ts │ │ └── example.ts │ ├── tsconfig.json │ ├── LICENSE │ ├── package.json │ └── README.md ├── coingeckoMaopPlugin │ ├── src │ │ ├── index.ts │ │ ├── example.ts │ │ ├── example.coinDataByID.ts │ │ ├── example.coinsCategoriesList.ts │ │ ├── example.coinPricesByIDs.ts │ │ ├── example.trendingSearchList.ts │ │ ├── example.trendingPoolsList.ts │ │ ├── example.newPoolsByNetwork.ts │ │ ├── example.coinsListWithMarketData.ts │ │ ├── example.tokenInfoByAddress.ts │ │ ├── example.trendingPoolsByNetwork.ts │ │ ├── example.topGainersLosersConfig.ts │ │ ├── example.coinPricesByAddress.ts │ │ ├── example.tokenPriceByAddresses.ts │ │ ├── example.specificPoolData.ts │ │ └── utils.ts │ └── package.json └── plugin_metadata_template.yml ├── .npmignore ├── examples ├── .env.example ├── tsconfig.json ├── README.md ├── state-management │ ├── index.ts │ └── agent.ts ├── package.json └── chat-agent-example │ └── telegram-with-chatAgent-example.ts ├── game-starter ├── .gitignore ├── .env.example ├── .dockerignore ├── tsconfig.json ├── src │ ├── index.ts │ ├── worker.ts │ └── agent.ts ├── rofl-compose.yml ├── docker-compose.yml ├── package.json ├── rofl.yaml └── Dockerfile ├── .gitignore ├── docs └── imgs │ ├── new_sdk_visual.png │ ├── old_sdk_visual.png │ ├── GAME-framework.jpeg │ └── game-cloud-json.png ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── pr-labeler-config.yml ├── workflows │ └── pr-labeler.yml ├── ISSUE_TEMPLATE │ └── feature_request.md └── PULL_REQUEST_TEMPLATE │ ├── default.md │ └── plugin.md ├── tools ├── README.md └── cloud-to-sdk │ ├── package.json │ ├── types.ts │ ├── generateWorker.ts │ ├── generateAgent.ts │ └── README.md ├── src ├── index.ts └── interface │ └── GameClient.ts ├── package.json └── LICENSE /.nvmrc: -------------------------------------------------------------------------------- 1 | v18.18.2 2 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | ./coverage 2 | -------------------------------------------------------------------------------- /examples/.env.example: -------------------------------------------------------------------------------- 1 | API_KEY=YOUR_GAME_SDK_API_KEY -------------------------------------------------------------------------------- /plugins/attpsPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/rss3Plugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/s3Plugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /game-starter/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules 3 | dist/ -------------------------------------------------------------------------------- /plugins/adNetworkPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/alchemyPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/alloraPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/alloraPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/attpsPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/discordPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/farcasterPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/rss3Plugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/twitterPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/twitterPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/zytronPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/adNetworkPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/evalEnginePlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/farcasterPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /plugins/s3Plugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | .env -------------------------------------------------------------------------------- /plugins/telegramPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/acpPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | example 3 | tsconfig.json 4 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ensoPlugin"; 2 | -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/recallStoragePlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | -------------------------------------------------------------------------------- /plugins/alchemyPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | coverage/ -------------------------------------------------------------------------------- /plugins/d.a.t.aPlugin/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | tsconfig.json 3 | .gitignore -------------------------------------------------------------------------------- /plugins/discordPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | coverage/ -------------------------------------------------------------------------------- /plugins/recallStoragePlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | .env -------------------------------------------------------------------------------- /plugins/telegramPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | coverage/ -------------------------------------------------------------------------------- /plugins/d.a.t.aPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | .env 4 | *.log -------------------------------------------------------------------------------- /plugins/evalEnginePlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | .env 4 | *.lock -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/tests/test-scenarios/market-analyst.ts: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/jest.setup.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config({ path: '.env' }); -------------------------------------------------------------------------------- /plugins/ensoPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | 4 | .env 5 | src/.env 6 | -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./onChainActionsPlugin"; 2 | -------------------------------------------------------------------------------- /plugins/stateofmikaPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './stateMikaPlugin'; 2 | -------------------------------------------------------------------------------- /plugins/zytronPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | 4 | .env 5 | src/.env 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | .env 4 | *.lock 5 | 6 | # JetBrains IDEs 7 | .idea/ 8 | -------------------------------------------------------------------------------- /plugins/attpsPlugin/.env.example: -------------------------------------------------------------------------------- 1 | PROXY_ADDRESS= 2 | PRIVATE_KEY= 3 | RPC_URL= 4 | AGENT_API_KEY= -------------------------------------------------------------------------------- /plugins/d.a.t.aPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export { createDataPlugin, DataPlugin } from "./d.a.t.aPlugin"; -------------------------------------------------------------------------------- /plugins/s3Plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import S3Plugin from "./s3Plugin"; 2 | 3 | export default S3Plugin; 4 | -------------------------------------------------------------------------------- /plugins/attpsPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import AttpsPlugin from "./attpsPlugin"; 2 | 3 | export default AttpsPlugin; -------------------------------------------------------------------------------- /plugins/dpsnPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import DpsnPlugin from './dpsnPlugin'; 2 | 3 | export default DpsnPlugin; 4 | -------------------------------------------------------------------------------- /plugins/rss3Plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import RSS3Plugin from "./rss3Plugin"; 2 | 3 | export default RSS3Plugin; 4 | -------------------------------------------------------------------------------- /plugins/twitterPlugin/example/.env.example: -------------------------------------------------------------------------------- 1 | GAME_TWITTER_ACCESS_TOKEN=apx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 2 | -------------------------------------------------------------------------------- /docs/imgs/new_sdk_visual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/docs/imgs/new_sdk_visual.png -------------------------------------------------------------------------------- /docs/imgs/old_sdk_visual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/docs/imgs/old_sdk_visual.png -------------------------------------------------------------------------------- /plugins/alchemyPlugin/.env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_API_KEY=your_alchemy_api_key 2 | VIRTUALS_API_TOKEN=your_virtuals_api_token -------------------------------------------------------------------------------- /plugins/alchemyPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import AlchemyPlugin from "./alchemyPlugin"; 2 | 3 | export default AlchemyPlugin; -------------------------------------------------------------------------------- /plugins/alloraPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import AlloraPlugin from "./alloraPlugin"; 2 | 3 | export default AlloraPlugin; 4 | -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/src/cache.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | latestEncryptedNumber: "", 3 | lastVoteTs: 0, 4 | } -------------------------------------------------------------------------------- /docs/imgs/GAME-framework.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/docs/imgs/GAME-framework.jpeg -------------------------------------------------------------------------------- /docs/imgs/game-cloud-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/docs/imgs/game-cloud-json.png -------------------------------------------------------------------------------- /plugins/discordPlugin/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | }; -------------------------------------------------------------------------------- /plugins/discordPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import DiscordPlugin from "./discordPlugin"; 2 | 3 | export default DiscordPlugin; 4 | -------------------------------------------------------------------------------- /plugins/imageGenPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import ImageGenPlugin from "./imageGenPlugin"; 2 | 3 | export default ImageGenPlugin; -------------------------------------------------------------------------------- /plugins/telegramPlugin/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | }; -------------------------------------------------------------------------------- /plugins/twitterPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import TwitterPlugin from "./twitterPlugin"; 2 | 3 | export default TwitterPlugin; 4 | -------------------------------------------------------------------------------- /plugins/evalEnginePlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import TwitterPlugin from "./twitterPlugin"; 2 | 3 | export default TwitterPlugin; 4 | -------------------------------------------------------------------------------- /plugins/telegramPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import TelegramPlugin from "./telegramPlugin"; 2 | 3 | export default TelegramPlugin; 4 | -------------------------------------------------------------------------------- /plugins/adNetworkPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import AdNetworkPlugin from "./adNetworkPlugin"; 2 | 3 | export default AdNetworkPlugin; 4 | -------------------------------------------------------------------------------- /plugins/farcasterPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import FarcasterPlugin from "./farcasterPlugin"; 2 | 3 | export default FarcasterPlugin; 4 | -------------------------------------------------------------------------------- /plugins/echochambersPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import EchochambersPlugin from './echochambersPlugin'; 2 | export default EchochambersPlugin; 3 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/src/.env.example: -------------------------------------------------------------------------------- 1 | WALLET_PRIVATE_KEY= 2 | RPC_PROVIDER_URL= 3 | ENSO_API_KEY=1e02632d-6feb-4a75-a157-documentation 4 | -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import MindNetworkPlugin from "./mindNetworkPlugin"; 2 | 3 | export default MindNetworkPlugin; 4 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/.env.example: -------------------------------------------------------------------------------- 1 | # DESK Exchange Plugin Configuration 2 | 3 | DESK_EXCHANGE_PRIVATE_KEY= 4 | 5 | DESK_EXCHANGE_NETWORK= -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import DeskExchangePlugin from './deskExchangePlugin' 2 | 3 | export default DeskExchangePlugin 4 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import CoingeckoMAOPPlugin from "./coingeckoMaopPlugin"; 2 | 3 | export default CoingeckoMAOPPlugin; 4 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/__test__/log.ts: -------------------------------------------------------------------------------- 1 | import { log } from 'console' 2 | 3 | export const logger = (msg: string): void => { 4 | log(msg) 5 | } 6 | -------------------------------------------------------------------------------- /plugins/recallStoragePlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import RecallStoragePlugin from "./recallStoragePlugin.js"; 2 | 3 | export default RecallStoragePlugin; 4 | -------------------------------------------------------------------------------- /plugins/twitterPlugin/example/media_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/twitterPlugin/example/media_file.png -------------------------------------------------------------------------------- /plugins/twitterPlugin/example/virtuals-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/twitterPlugin/example/virtuals-logo.png -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/screenshots/Chat-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/tokenMetricsPlugin/screenshots/Chat-1.png -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/screenshots/Chat-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/tokenMetricsPlugin/screenshots/Chat-2.png -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/screenshots/Setup-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/tokenMetricsPlugin/screenshots/Setup-1.png -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/screenshots/Setup-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/tokenMetricsPlugin/screenshots/Setup-2.png -------------------------------------------------------------------------------- /plugins/dpsnPlugin/coverage/lcov-report/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/dpsnPlugin/coverage/lcov-report/favicon.png -------------------------------------------------------------------------------- /game-starter/.env.example: -------------------------------------------------------------------------------- 1 | API_KEY=YOUR_GAME_SDK_API_KEY 2 | WEATHER_API_KEY=YOUR_WEATHER_API_KEY 3 | OPENAI_API_KEY=YOUR_OPENAI_API_KEY 4 | botToken=YOUR_TELEGRAM_BOT_TOKEN -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | setupFiles: ['/jest.setup.js'], 5 | } -------------------------------------------------------------------------------- /plugins/stateofmikaPlugin/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | testMatch: ['**/__tests__/**/*.test.ts'], 5 | }; 6 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/coverage/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/dpsnPlugin/coverage/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/screenshots/Quantmetics Example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/tokenMetricsPlugin/screenshots/Quantmetics Example.png -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Click the `Preview` tab and select a PR template: 2 | 3 | - [Default Template](?expand=1&template=default.md) 4 | - [Plugin](?expand=1&template=plugin.md) 5 | -------------------------------------------------------------------------------- /plugins/d.a.t.aPlugin/.env.example: -------------------------------------------------------------------------------- 1 | # GAME 2 | GAME_API_KEY=your-game-api-key 3 | 4 | # CARV D.A.T.A. API Configuration 5 | CARV_DATA_API_KEY=your-api-key 6 | CARV_DATA_AUTH_TOKEN=your-auth-token -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/screenshots/Market Sentiment Example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/game-by-virtuals/game-node/HEAD/plugins/tokenMetricsPlugin/screenshots/Market Sentiment Example.png -------------------------------------------------------------------------------- /plugins/recallStoragePlugin/.env.example: -------------------------------------------------------------------------------- 1 | GAME_API_KEY=xxxxxxxxxxxxxxxxxxxx 2 | RECALL_PRIVATE_KEY=0xyour_private_key 3 | RECALL_BUCKET_ALIAS=game-agent 4 | RECALL_PREFIX=cot/ 5 | RECALL_NETWORK=testnet -------------------------------------------------------------------------------- /plugins/zytronPlugin/src/utils.ts: -------------------------------------------------------------------------------- 1 | export const isValidNumber = (input?: string): boolean => { 2 | if (typeof input !== "string") return false; 3 | return /^[0-9]+(\.[0-9]+)?$/.test(input); 4 | } 5 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/.gitignore: -------------------------------------------------------------------------------- 1 | #dependencies 2 | node_modules/ 3 | 4 | #env 5 | .env 6 | 7 | #build 8 | dist/ 9 | 10 | #IDE 11 | .vscode/ 12 | .idea/ 13 | 14 | #test 15 | coverage/ 16 | -------------------------------------------------------------------------------- /plugins/zytronPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import ZytronPlugin from './zytronPlugin'; 2 | import ZytronWallet from './zytronWallet'; 3 | 4 | export default ZytronPlugin; 5 | export { ZytronPlugin, ZytronWallet }; 6 | -------------------------------------------------------------------------------- /plugins/acpPlugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import AcpPlugin from "./acpPlugin"; 2 | import { AcpJobPhasesDesc, IAcpJob, AcpState } from "./interface"; 3 | 4 | export default AcpPlugin; 5 | export { AcpJobPhasesDesc, IAcpJob, AcpState }; 6 | -------------------------------------------------------------------------------- /plugins/s3Plugin/.env.example: -------------------------------------------------------------------------------- 1 | S3_ACCESS_KEY_ID=xxxxxxx 2 | S3_SECRET_ACCESS_KEY=xxxxxxx 3 | S3_REGION=xxxxxxx 4 | S3_BUCKET=xxxxxxx 5 | S3_ENDPOINT=xxxxxxx 6 | S3_SSL_ENABLED=true 7 | S3_FORCE_PATH_STYLE=false 8 | GAME_API_KEY=xxxxxxx -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/src/.env.example: -------------------------------------------------------------------------------- 1 | WALLET_PRIVATE_KEY= 2 | RPC_PROVIDER_URL= 3 | UNISWAP_API_KEY=kHEhfIPvCE3PO5PeT0rNb1CA3JJcnQ8r7kJDXN5X # Public key to test with 4 | UNISWAP_BASE_URL=https://trade-api.gateway.uniswap.org/v1 5 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entry: ['./src/index.ts'], 5 | outDir: 'dist', 6 | sourcemap: true, 7 | clean: true, 8 | format: ['esm'], 9 | }) 10 | -------------------------------------------------------------------------------- /plugins/alchemyPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/__test__/__mocks__/dpsn-client.ts: -------------------------------------------------------------------------------- 1 | import mockDpsnClient from '../mocks/dpsnClient.mock'; 2 | 3 | // Export the mock client as the default export 4 | const MockDpsnClient = jest.fn().mockImplementation(() => { 5 | return mockDpsnClient; 6 | }); 7 | 8 | export default MockDpsnClient; 9 | -------------------------------------------------------------------------------- /plugins/attpsPlugin/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface AttpsPriceQueryResponse { 2 | feedId: string 3 | validTimeStamp: number 4 | observeTimeStamp: number 5 | nativeFee: number 6 | tokenFee: number 7 | expireTimeStamp: number 8 | midPrice: string 9 | askPrice: string 10 | bidPrice: string 11 | } -------------------------------------------------------------------------------- /plugins/stateofmikaPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | 4 | # Build 5 | dist/ 6 | 7 | # Coverage 8 | coverage/ 9 | 10 | # IDE 11 | .vscode/ 12 | .idea/ 13 | 14 | # Logs 15 | *.log 16 | 17 | # Environment 18 | .env 19 | .env.local 20 | .env.*.local 21 | 22 | # OS 23 | .DS_Store 24 | Thumbs.db 25 | -------------------------------------------------------------------------------- /examples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "../", // Look up one directory to include everything 5 | "outDir": "./dist" 6 | }, 7 | "include": [ 8 | "./**/*", // Include all example files 9 | "../plugins/**/example.ts" // Include plugin examples 10 | ] 11 | } -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | # Tools 2 | 3 | This directory contains tools that help with the development of the SDK. 4 | 5 | ## Available Tools 6 | 7 | ### cloud-to-sdk 8 | Converts GAME cloud configuration JSON files into SDK-compatible TypeScript files. 9 | Please refer to the [cloud-to-sdk/README.md](cloud-to-sdk/README.md) for more information on how to use this tool. -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/env.example: -------------------------------------------------------------------------------- 1 | # TokenMetrics API Configuration 2 | TOKENMETRICS_API_KEY=tm-your-tokenmetrics-api-key-here 3 | 4 | # Virtuals Protocol GAME API Configuration 5 | GAME_API_KEY=your-game-api-key-here 6 | 7 | # Optional: Custom TokenMetrics API Base URL (if using different endpoint) 8 | # TOKENMETRICS_BASE_URL=https://api.tokenmetrics.com/v2 9 | -------------------------------------------------------------------------------- /.github/pr-labeler-config.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | appendOnly: true 3 | labels: 4 | - label: "bugfix" 5 | title: "(?i)fix|bug" 6 | - label: "documentation" 7 | title: "(?i)docs|documentation" 8 | - label: "enhancement" 9 | title: "(?i)feat|feature|enhance|improve" 10 | - label: "plugin" 11 | title: "(?i)plugin" 12 | - label: "test" 13 | title: "(?i)test" 14 | -------------------------------------------------------------------------------- /plugins/echochambersPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./dist", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true 11 | }, 12 | "include": ["src"], 13 | "exclude": ["node_modules", "dist"] 14 | } 15 | -------------------------------------------------------------------------------- /game-starter/.dockerignore: -------------------------------------------------------------------------------- 1 | # .dockerignore 2 | 3 | # Ignore node_modules from the build context 4 | node_modules 5 | 6 | # Ignore logs and temporary files 7 | *.log 8 | *.tmp 9 | .DS_Store 10 | 11 | # Ignore Git files and metadata 12 | .git 13 | .gitignore 14 | 15 | # Ignore IDE and editor config files 16 | .vscode 17 | .idea 18 | *.swp 19 | 20 | # Ignore build artifacts from the host 21 | dist 22 | build 23 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This directory contains example implementations showing how to use the library with different platforms. 4 | 5 | ## Running the Examples 6 | 7 | 1. Create a `.env` file in each example directory (telegram-example and twitter-example) using the `.env.example` as template 8 | 9 | 2. Run the examples using: 10 | 11 | npm run telegram-example # for telegram bot 12 | npm run twitter-example # for twitter bot -------------------------------------------------------------------------------- /plugins/attpsPlugin/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import { defineConfig } from 'vitest/config' 3 | import dotenv from 'dotenv' 4 | 5 | export default defineConfig({ 6 | test: { 7 | testTimeout: 300000, 8 | env: dotenv.config().parsed, 9 | }, 10 | resolve: { 11 | alias: { 12 | '@': path.resolve(__dirname, './src'), 13 | '@test': path.resolve(__dirname, './test'), 14 | }, 15 | }, 16 | }) 17 | -------------------------------------------------------------------------------- /plugins/d.a.t.aPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./dist", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["node_modules", "dist"] 14 | } -------------------------------------------------------------------------------- /game-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "declaration": true, 11 | "forceConsistentCasingInFileNames": true, 12 | }, 13 | "include": [ 14 | "src/**/*" 15 | ], 16 | "exclude": [ 17 | "node_modules" 18 | ] 19 | } -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": ".", 6 | "types": [ 7 | "node" 8 | ], 9 | "moduleResolution": "bundler", 10 | "module": "ESNext", 11 | }, 12 | "include": [ 13 | "./src/**/*.ts", 14 | "./__test__/**/*.ts", 15 | "./__test__/**/*.test.ts" 16 | ] 17 | } -------------------------------------------------------------------------------- /plugins/evalEnginePlugin/src/evalEngine.ts: -------------------------------------------------------------------------------- 1 | import { CHROMIA_CHAIN, EvalClient } from "eval-engine-sdk"; 2 | 3 | export const initEvalClient = async (privateKey: string) => { 4 | const evalClient = await EvalClient.init(privateKey, CHROMIA_CHAIN.MAINNET, { 5 | url: "https://api.evalengine.ai/api", 6 | prefix: "EVA", 7 | pub: "026822066B64608E0A6E071D8AE76BDE509011FF823DBBF9FD6AC2E1F202904A0A", 8 | }); 9 | 10 | return evalClient; 11 | }; 12 | -------------------------------------------------------------------------------- /game-starter/src/index.ts: -------------------------------------------------------------------------------- 1 | import { activity_agent } from './agent'; 2 | 3 | async function main() { 4 | try { 5 | // Initialize the agent 6 | await activity_agent.init(); 7 | 8 | // Run the agent 9 | while (true) { 10 | await activity_agent.step({ verbose: true }); 11 | } 12 | } catch (error) { 13 | console.error("Error running activity recommender:", error); 14 | } 15 | } 16 | 17 | main(); -------------------------------------------------------------------------------- /game-starter/rofl-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | game-starter: 3 | image: docker.io//virtuals-game-starter 4 | build: 5 | context: . 6 | dockerfile: Dockerfile 7 | platform: linux/amd64 8 | environment: 9 | - API_KEY=${API_KEY} 10 | - WEATHER_API_KEY=${WEATHER_API_KEY} 11 | - OPENAI_API_KEY=${OPENAI_API_KEY} 12 | volumes: 13 | - virtuals:/app 14 | restart: always 15 | 16 | volumes: 17 | virtuals: 18 | -------------------------------------------------------------------------------- /examples/state-management/index.ts: -------------------------------------------------------------------------------- 1 | import { agent } from './agent'; 2 | import dotenv from 'dotenv'; 3 | dotenv.config(); 4 | 5 | async function main() { 6 | try { 7 | // Initialize the agent 8 | await agent.init(); 9 | 10 | // Run the agent 11 | while (true) { 12 | await agent.step({ verbose: true }); 13 | } 14 | } catch (error) { 15 | console.error("Error running kitchen manager:", error); 16 | } 17 | } 18 | 19 | main(); -------------------------------------------------------------------------------- /plugins/zytronPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "outDir": "./dist", 10 | "declaration": true, 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true 13 | }, 14 | "include": ["src/**/*", "__tests__/**/*"], 15 | "exclude": ["node_modules", "dist"] 16 | } 17 | -------------------------------------------------------------------------------- /plugins/stateofmikaPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "outDir": "./dist", 10 | "declaration": true, 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true 13 | }, 14 | "include": ["src/**/*", "__tests__/**/*"], 15 | "exclude": ["node_modules", "dist"] 16 | } 17 | -------------------------------------------------------------------------------- /game-starter/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | game-starter: 3 | image: virtuals-game-starter 4 | build: 5 | context: . 6 | dockerfile: Dockerfile 7 | platform: linux/amd64 8 | environment: 9 | - API_KEY= 10 | - WEATHER_API_KEY= 11 | - OPENAI_API_KEY= 12 | - OPENAI_BASE_URL= 13 | - botToken= 14 | volumes: 15 | - /var/run/tappd.sock:/var/run/tappd.sock 16 | - virtuals:/app 17 | restart: always 18 | 19 | volumes: 20 | virtuals: 21 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import GameAgent from "./agent"; 2 | import GameWorker from "./worker"; 3 | import GameFunction, { 4 | ExecutableGameFunctionResponse, 5 | ExecutableGameFunctionStatus, 6 | } from "./function"; 7 | import { LLMModel } from "./interface/GameClient"; 8 | import { ChatAgent, Chat } from "./chatAgent"; 9 | 10 | export { 11 | GameAgent, 12 | GameFunction, 13 | GameWorker, 14 | ExecutableGameFunctionResponse, 15 | ExecutableGameFunctionStatus, 16 | LLMModel, 17 | ChatAgent, 18 | Chat, 19 | }; 20 | -------------------------------------------------------------------------------- /plugins/twitterPlugin/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twitter-plugin-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@virtuals-protocol/game": "^0.1.7", 13 | "@virtuals-protocol/game-twitter-plugin": "^0.1.4", 14 | "@virtuals-protocol/game-twitter-node": "^0.1.0", 15 | "axios": "^1.7.7", 16 | "dotenv": "^16.4.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/pr-labeler.yml: -------------------------------------------------------------------------------- 1 | name: Auto Label PR 2 | 3 | on: 4 | pull_request: 5 | branches: [ "main" ] 6 | types: [ opened, edited, reopened, synchronize ] 7 | 8 | jobs: 9 | label-plugin-pr: 10 | permissions: 11 | contents: read 12 | pull-requests: write 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Auto Apply Labels 16 | uses: srvaroa/labeler@master 17 | with: 18 | config_path: .github/pr-labeler-config.yml 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples", 3 | "private": true, 4 | "dependencies": { 5 | "@virtuals-protocol/game": "^0.1.9", 6 | "dotenv": "^16.4.7", 7 | "openai": "^4.81.0", 8 | "twitter-api-v2": "^1.15.0" 9 | }, 10 | "scripts": { 11 | "start": "ts-node -P ./tsconfig.json", 12 | "build": "tsc -p ./tsconfig.json", 13 | "twitter-example": "ts-node twitter-example/twitter.ts", 14 | "telegram-example": "ts-node telegram-example/tg.ts", 15 | "state-management": "ts-node state-management/index.ts" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020"], 6 | "outDir": "./dist", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "declaration": true, 13 | "declarationMap": true, 14 | "sourceMap": true, 15 | "resolveJsonModule": true 16 | }, 17 | "include": ["src/**/*"], 18 | "exclude": ["node_modules", "dist"] 19 | } 20 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/__test__/setup.ts: -------------------------------------------------------------------------------- 1 | // Jest setup file 2 | import dotenv from 'dotenv'; 3 | import path from 'path'; 4 | 5 | // Load environment variables from .env file 6 | dotenv.config({ path: path.resolve(__dirname, "../../../.env") }); 7 | 8 | // Set default timeout for tests 9 | jest.setTimeout(60000); // Increased to 60 seconds 10 | 11 | // Global mocks and setup 12 | global.console = { 13 | ...console, 14 | // You can customize console behavior for tests if needed 15 | log: jest.fn(), 16 | error: jest.fn(), 17 | warn: jest.fn(), 18 | info: jest.fn(), 19 | }; 20 | -------------------------------------------------------------------------------- /game-starter/src/worker.ts: -------------------------------------------------------------------------------- 1 | import { GameWorker } from "@virtuals-protocol/game"; 2 | import { getWeatherFunction, getLocationFunction, recommendActivitiesFunction } from "./functions"; 3 | 4 | // Create a demo worker with our functions 5 | export const activityRecommenderWorker = new GameWorker({ 6 | id: "activity_recommender", 7 | name: "Activity Recommender", 8 | description: "Gets location and weather information and recommends activities", 9 | functions: [ 10 | getLocationFunction, 11 | getWeatherFunction, 12 | recommendActivitiesFunction 13 | ] 14 | }); -------------------------------------------------------------------------------- /tools/cloud-to-sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-cloud-to-sdk", 3 | "version": "0.1.0", 4 | "description": "Tool to convert GAME cloud configuration JSON files into SDK-compatible TypeScript files", 5 | "main": "index.ts", 6 | "scripts": { 7 | "start": "ts-node index.ts", 8 | "build": "tsc", 9 | "cloud-to-sdk": "ts-node index.ts" 10 | }, 11 | "dependencies": { 12 | "@virtuals-protocol/game": "^1.0.0", 13 | "ts-node": "^10.9.1", 14 | "typescript": "^5.0.0" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^18.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | testMatch: ['**/__test__/**/*.test.ts'], 5 | collectCoverage: true, 6 | collectCoverageFrom: [ 7 | 'src/**/*.ts', 8 | '!src/example.ts', 9 | '!src/index.ts' 10 | ], 11 | coverageDirectory: 'coverage', 12 | coverageReporters: ['text', 'lcov'], 13 | transform: { 14 | '^.+\\.tsx?$': ['ts-jest', { 15 | tsconfig: 'tsconfig.json', 16 | }], 17 | }, 18 | moduleNameMapper: { 19 | '^@/(.*)$': '/src/$1', 20 | }, 21 | setupFilesAfterEnv: ['/__test__/setup.ts'], 22 | }; 23 | -------------------------------------------------------------------------------- /plugins/s3Plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 4 | "module": "commonjs" /* Specify what module code is generated. */, 5 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 6 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 7 | "strict": true /* Enable all strict type-checking options. */, 8 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/coverage/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /plugins/d.a.t.aPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@game-node/d.a.t.a-plugin", 3 | "version": "1.0.0", 4 | "description": "D.A.T.A Plugin for SQL query execution and data analysis", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "tsc", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [ 12 | "data", 13 | "sql", 14 | "query", 15 | "analysis" 16 | ], 17 | "author": "", 18 | "license": "ISC", 19 | "dependencies": { 20 | "@virtuals-protocol/game": "^0.1.7", 21 | "dotenv": "^16.4.7" 22 | }, 23 | "devDependencies": { 24 | "ts-node": "^10.9.2", 25 | "typescript": "^5.0.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /game-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "game-starter", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "start": "node dist/index.js", 9 | "plugin": "node dist/plugins/example.js", 10 | "dev": "ts-node src/index.ts", 11 | "watch": "tsc --watch" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "@types/node": "^22.12.0", 18 | "ts-node": "^10.9.2", 19 | "typescript": "^5.7.3" 20 | }, 21 | "dependencies": { 22 | "@types/dotenv": "^6.1.1", 23 | "@virtuals-protocol/game": "^0.1.9", 24 | "dotenv": "^16.4.7", 25 | "openai": "^4.81.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/default.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | One-liner - what does this change? 4 | 5 | ## Changes 6 | 7 | (Answer where applicable) 8 | 9 | - Important links (Jira/Notion/GitHub Issues): 10 | - Why this PR is needed? 11 | - What does this add? 12 | - What does this deprecate? 13 | - What does this improve? 14 | 15 | ## Related Changes 16 | 17 | - Does this have a dependant PR? Eg. link to original PR if this is a bug fix PR. 18 | 19 | (Use table to list all related PRs if done in parts) 20 | 21 | | Description | PR | 22 | | --- | --- | 23 | | [Part 1] This PR | ⬅️ | 24 | | [Part 2] Another PR | link | 25 | | [Part 3] Another PR | link | 26 | 27 | ## Dev Testing 28 | 29 | (Include where applicable) 30 | 31 | - Screenshots 32 | - Video Recordings 33 | -------------------------------------------------------------------------------- /plugins/zytronPlugin/src/constants.ts: -------------------------------------------------------------------------------- 1 | import { Chain } from "viem"; 2 | 3 | export const zytron = { 4 | id: 9901, 5 | name: "Zytron Mainnet", 6 | nativeCurrency: { name: 'ETHEREUM', symbol: 'ETH', decimals: 18 }, 7 | rpcUrls: { 8 | default: { 9 | http: ['https://rpc.zypher.network'] 10 | }, 11 | }, 12 | blockExplorers: { 13 | default: { name: "Zytron Mainnet Explorer", url: 'https://explorer.zypher.network/' } 14 | }, 15 | contracts: { 16 | multicall3: { 17 | address: '0xa8fAD960aCf062715e1fd3DBD0ee319B2d753b23', 18 | }, 19 | }, 20 | testnet: false, 21 | } as const satisfies Chain; 22 | 23 | 24 | export const SupportedToken = { 25 | ETH: '0x0000000000000000000000000000000000000000', 26 | } as Record; 27 | 28 | -------------------------------------------------------------------------------- /plugins/recallStoragePlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 4 | "module": "NodeNext" /* Specify what module code is generated. */, 5 | "moduleResolution": "NodeNext" /* Specify how modules are resolved. */, 6 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 7 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 8 | "strict": true /* Enable all strict type-checking options. */, 9 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /plugins/echochambersPlugin/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Message { 2 | id: string; 3 | content: string; 4 | sender: { 5 | username: string; 6 | model: string; 7 | }; 8 | timestamp: string; 9 | roomId: string; 10 | } 11 | 12 | export interface RoomHistory { 13 | messages: Message[]; 14 | roomId: string; 15 | } 16 | 17 | export interface Metric { 18 | category: string; 19 | value: number; 20 | maxValue: number; 21 | description: string; 22 | } 23 | 24 | export interface AgentMetrics { 25 | agent: string; 26 | metrics: Metric[]; 27 | } 28 | 29 | export interface RoomMetrics { 30 | metrics: Metric[]; 31 | agentMetrics: AgentMetrics[]; 32 | lastUpdated: number; 33 | } 34 | 35 | export interface MetricsHistory { 36 | roomMetrics: Array<{ 37 | metrics: Metric[]; 38 | }>; 39 | } 40 | -------------------------------------------------------------------------------- /plugins/rss3Plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-rss3-plugin", 3 | "version": "0.1", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2" 17 | }, 18 | "dependencies": { 19 | "@rss3/sdk": "^0.0.23", 20 | "@virtuals-protocol/game": "^0.1.4", 21 | "tsup": "^8.3.5" 22 | }, 23 | "files": [ 24 | "dist" 25 | ], 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/game-by-virtuals/game-node" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugins/zytronPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-zytron-plugin", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "build": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 10 | }, 11 | "author": "", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "@types/node": "^22.13.10", 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.8.2", 17 | "vitest": "^3.0.9" 18 | }, 19 | "dependencies": { 20 | "@virtuals-protocol/game": "^0.1.10", 21 | "tsup": "^8.4.0", 22 | "viem": "^2.23.13" 23 | }, 24 | "files": [ 25 | "dist" 26 | ], 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/game-by-virtuals/game-node" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /plugins/alloraPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-allora-plugin", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2" 17 | }, 18 | "dependencies": { 19 | "@virtuals-protocol/game": "^0.1.4", 20 | "tsup": "^8.3.5", 21 | "@alloralabs/allora-sdk": "^0.1.0" 22 | }, 23 | "files": [ 24 | "dist" 25 | ], 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/game-by-virtuals/game-node" 29 | } 30 | } -------------------------------------------------------------------------------- /plugins/attpsPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 4 | "module": "commonjs", /* Specify what module code is generated. */ 5 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 6 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 7 | "strict": true, /* Enable all strict type-checking options. */ 8 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 4 | "module": "commonjs", /* Specify what module code is generated. */ 5 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 6 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 7 | "strict": true, /* Enable all strict type-checking options. */ 8 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/alloraPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 4 | "module": "commonjs", /* Specify what module code is generated. */ 5 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 6 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 7 | "strict": true, /* Enable all strict type-checking options. */ 8 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 4 | "module": "commonjs", /* Specify what module code is generated. */ 5 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 6 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 7 | "strict": true, /* Enable all strict type-checking options. */ 8 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/adNetworkPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/ad-network-plugin", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts src/example.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2" 17 | }, 18 | "dependencies": { 19 | "@virtuals-protocol/game": "^0.1.9", 20 | "@virtuals-protocol/game-twitter-plugin": "^0.1.1", 21 | "tsup": "^8.3.5" 22 | }, 23 | "files": [ 24 | "dist" 25 | ], 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/game-by-virtuals/game-node" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game", 3 | "version": "0.1.14", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "build": "tsc", 11 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 12 | }, 13 | "author": "", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "@types/jsonwebtoken": "^9.0.7", 17 | "@types/node": "^22.10.3", 18 | "ts-node-dev": "^2.0.0", 19 | "tsup": "^8.3.5", 20 | "typescript": "^5.7.2" 21 | }, 22 | "dependencies": { 23 | "axios": "^1.7.9", 24 | "dotenv": "^16.4.7" 25 | }, 26 | "files": [ 27 | "dist" 28 | ], 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/game-by-virtuals/game-node" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugins/attpsPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-attps-plugin", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "vitest run", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "dotenv": "^16.4.7", 16 | "ts-node-dev": "^2.0.0", 17 | "typescript": "^5.7.2", 18 | "vite": "^6.0.11", 19 | "vitest": "^3.0.4" 20 | }, 21 | "dependencies": { 22 | "@virtuals-protocol/game": "^0.1.7", 23 | "attps-sdk-js": "^0.1.0", 24 | "tsup": "^8.3.5" 25 | }, 26 | "files": [ 27 | "dist" 28 | ], 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/game-by-virtuals/game-node" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugins/evalEnginePlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-eval-engine-plugin", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2" 17 | }, 18 | "dependencies": { 19 | "@virtuals-protocol/game": "^0.1.4", 20 | "eval-engine-sdk": "^0.0.6", 21 | "tsup": "^8.3.5", 22 | "twitter-api-v2": "^1.19.0" 23 | }, 24 | "files": [ 25 | "dist" 26 | ], 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/game-by-virtuals/game-node" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /plugins/farcasterPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-farcaster-plugin", 3 | "version": "0.1.3", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2" 17 | }, 18 | "dependencies": { 19 | "@coinbase/agentkit": "^0.1.1", 20 | "@coinbase/agentkit-langchain": "^0.1.0", 21 | "@virtuals-protocol/game": "^0.1.7", 22 | "tsup": "^8.3.5" 23 | }, 24 | "files": [ 25 | "dist" 26 | ], 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/game-by-virtuals/game-node" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game"; 2 | import MindNetworkPlugin from "."; 3 | 4 | const mindNetworkPlugin = new MindNetworkPlugin({}); 5 | 6 | // Create an agent with the worker 7 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 8 | name: "Mind Network Voter", 9 | goal: "Get the reward amount earned for voting with FHE.", 10 | description: `You are an AI agent specialized in Mind Network. Check the voting reward I have earned so far.`, 11 | workers: [ 12 | mindNetworkPlugin.getWorker({}), 13 | ], 14 | }); 15 | 16 | (async () => { 17 | agent.setLogger((agent, message) => { 18 | console.log(`-----[${agent.name}]-----`); 19 | console.log(message); 20 | console.log("\n"); 21 | }); 22 | 23 | await agent.init(); 24 | 25 | while (true) { 26 | await agent.step({ 27 | verbose: true, 28 | }); 29 | } 30 | })(); 31 | -------------------------------------------------------------------------------- /game-starter/rofl.yaml: -------------------------------------------------------------------------------- 1 | name: game-starter 2 | version: 0.1.0 3 | tee: tdx 4 | kind: container 5 | resources: 6 | memory: 512 7 | cpus: 1 8 | storage: 9 | kind: disk-persistent 10 | size: 10000 11 | artifacts: 12 | firmware: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.4.1/ovmf.tdx.fd#db47100a7d6a0c1f6983be224137c3f8d7cb09b63bb1c7a5ee7829d8e994a42f 13 | kernel: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.4.1/stage1.bin#06e12cba9b2423b4dd5916f4d84bf9c043f30041ab03aa74006f46ef9c129d22 14 | stage2: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.4.1/stage2-podman.tar.bz2#6f2487aa064460384309a58c858ffea9316e739331b5c36789bb2f61117869d6 15 | container: 16 | runtime: https://github.com/oasisprotocol/oasis-sdk/releases/download/rofl-containers%2Fv0.4.2/rofl-containers#0cbaa4c0c1b35c5ed41156868bee9f3726f52eeedc01b3060d3b2eb67d76f546 17 | compose: rofl-compose.yml 18 | -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-mind-network-plugin", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node": "^10.9.2", 16 | "ts-node-dev": "^2.0.0", 17 | "typescript": "^5.7.2" 18 | }, 19 | "dependencies": { 20 | "@virtuals-protocol/game": "^0.1.4", 21 | "ethers": "^6.13.5", 22 | "mind-randgen-sdk": "^1.0.2", 23 | "tsup": "^8.3.5" 24 | }, 25 | "files": [ 26 | "dist" 27 | ], 28 | "repository": { 29 | "type": "git", 30 | "url": "https://github.com/game-by-virtuals/game-node" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plugins/s3Plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-s3-plugin", 3 | "version": "0.1.3", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "dotenv": "^16.4.7", 16 | "ts-node-dev": "^2.0.0", 17 | "tsup": "^8.3.5", 18 | "typescript": "^5.7.2" 19 | }, 20 | "dependencies": { 21 | "@aws-sdk/client-s3": "^3.735.0", 22 | "@aws-sdk/s3-request-presigner": "^3.735.0", 23 | "@virtuals-protocol/game": "^0.1.7" 24 | }, 25 | "files": [ 26 | "dist" 27 | ], 28 | "repository": { 29 | "type": "git", 30 | "url": "https://github.com/game-by-virtuals/game-node" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-enso-plugin", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@types/node": "^22.13.9", 16 | "dotenv": "^16.4.7", 17 | "ts-node-dev": "^2.0.0", 18 | "typescript": "^5.7.2" 19 | }, 20 | "dependencies": { 21 | "@ensofinance/sdk": "^1.0.10", 22 | "@virtuals-protocol/game": "^0.1.4", 23 | "tsup": "^8.3.5", 24 | "viem": "^2.22.16" 25 | }, 26 | "files": [ 27 | "dist" 28 | ], 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/game-by-virtuals/game-node" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugins/evalEnginePlugin/src/tweet/get-tweet.ts: -------------------------------------------------------------------------------- 1 | // Modified code of https://github.com/vercel/react-tweet 2 | 3 | import { AxiosRequestConfig } from "axios"; 4 | import { fetchTweet } from "./fetch-tweet"; 5 | import type { Tweet } from "./tweet"; 6 | 7 | /** 8 | * Returns a tweet from the Twitter syndication API. 9 | */ 10 | export async function getTweet( 11 | id: string, 12 | fetchOptions?: AxiosRequestConfig 13 | ): Promise { 14 | const { data, tombstone, notFound } = await fetchTweet(id, fetchOptions); 15 | 16 | if (notFound) { 17 | console.error( 18 | `The tweet ${id} does not exist or has been deleted by the account owner. Update your code to remove this tweet when possible.` 19 | ); 20 | } else if (tombstone) { 21 | console.error( 22 | `The tweet ${id} has been made private by the account owner. Update your code to remove this tweet when possible.` 23 | ); 24 | } 25 | 26 | return data; 27 | } 28 | -------------------------------------------------------------------------------- /plugins/imageGenPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-imagegen-plugin", 3 | "version": "0.1.0", 4 | "description": "Image generation plugin for GAME SDK using Together AI", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "Chinese Powered Labs", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@types/node": "^22.13.1", 16 | "dotenv": "^16.4.7", 17 | "ts-node-dev": "^2.0.0", 18 | "typescript": "^5.7.3" 19 | }, 20 | "dependencies": { 21 | "@virtuals-protocol/game": "^0.1.4", 22 | "tsup": "^8.3.5" 23 | }, 24 | "files": [ 25 | "dist" 26 | ], 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/game-by-virtuals/game-node" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /plugins/twitterPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-twitter-plugin", 3 | "version": "0.1.11", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/*.ts --dts --format cjs --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2" 17 | }, 18 | "dependencies": { 19 | "@virtuals-protocol/game": "^0.1.7", 20 | "@virtuals-protocol/game-twitter-node": "^0.1.0", 21 | "@virtuals-protocol/game-twitter-plugin": "^0.1.9" 22 | }, 23 | "files": [ 24 | "dist" 25 | ], 26 | "bin": { 27 | "game-twitter-plugin": "./dist/bin.js" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/game-by-virtuals/game-node" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const ENSO_SUPPORTED_CHAINS = new Map([ 2 | [1, "ethereum"], 3 | [10, "optimism"], 4 | [56, "bnb chain"], 5 | [100, "gnosis"], 6 | [137, "polygon"], 7 | [324, "zksync"], 8 | [8453, "base"], 9 | [42161, "arbitrum"], 10 | [43114, "avalanche"], 11 | [59144, "linea"], 12 | [80094, "berachain"], 13 | ]); 14 | 15 | export const ENSO_ETH = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" as const; 16 | 17 | export const ERC20_ABI_MIN = [ 18 | { 19 | constant: false, 20 | inputs: [ 21 | { 22 | name: "_spender", 23 | type: "address", 24 | }, 25 | { 26 | name: "_value", 27 | type: "uint256", 28 | }, 29 | ], 30 | name: "approve", 31 | outputs: [ 32 | { 33 | name: "", 34 | type: "bool", 35 | }, 36 | ], 37 | payable: false, 38 | stateMutability: "nonpayable", 39 | type: "function", 40 | }, 41 | ] as const; 42 | -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 4 | "module": "commonjs", /* Specify what module code is generated. */ 5 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 6 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 7 | "strict": true, /* Enable all strict type-checking options. */ 8 | "skipLibCheck": true , /* Skip type checking all .d.ts files. */ 9 | "outDir": "./dist", /* Specify an output folder for all emitted files. */ 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tools/cloud-to-sdk/types.ts: -------------------------------------------------------------------------------- 1 | // types.ts 2 | export interface PluginJson { 3 | name: string; 4 | goal: string; 5 | description: string; 6 | gameEngineModel: string; 7 | workers: Worker[]; 8 | customFunctions: CustomFunction[]; 9 | } 10 | 11 | interface Worker { 12 | id: string; 13 | name: string; 14 | description: string; 15 | workerId: string; 16 | environment?: Record; 17 | isDefault?: boolean; 18 | deleted?: boolean; 19 | environmentString?: string; 20 | } 21 | 22 | interface CustomFunction { 23 | id: string; 24 | fn_name: string; 25 | fn_description: string; 26 | args: FunctionArg[]; 27 | hint?: string; 28 | config: { 29 | workerId: string; 30 | [key: string]: any; // For other config properties 31 | }; 32 | workerId?: string; 33 | } 34 | 35 | interface FunctionArg { 36 | id: string; 37 | name: string; 38 | description: string; 39 | type: string; 40 | } -------------------------------------------------------------------------------- /plugins/acpPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-acp-plugin", 3 | "version": "0.2.9", 4 | "main": "./dist/index.js", 5 | "module": "./dist/index.mjs", 6 | "types": "./dist/index.d.ts", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "description": "", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.8.2" 17 | }, 18 | "dependencies": { 19 | "@aa-sdk/core": "^4.21.0", 20 | "@account-kit/infra": "^4.21.0", 21 | "@account-kit/smart-contracts": "^4.21.0", 22 | "@types/node-fetch": "^2.6.12", 23 | "@virtuals-protocol/acp-node": "^0.2.0-beta.1", 24 | "@virtuals-protocol/game": "^0.1.14", 25 | "@virtuals-protocol/game-twitter-node": "^0.1.4", 26 | "socket.io-client": "^4.8.1", 27 | "tsup": "^8.4.0", 28 | "viem": "^2.23.10" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { ExecutableGameFunctionResponse, ExecutableGameFunctionStatus } from '@virtuals-protocol/game' 2 | 3 | import { FMT_ERRORS } from './constants' 4 | 5 | export function errorHandler(f: FMT_ERRORS, e: unknown, logger: (msg: string) => void) { 6 | let errorMessage: string 7 | // build message 8 | if (e instanceof Error) { 9 | errorMessage = f.replace('{{error}}', e.message) 10 | } else { 11 | errorMessage = FMT_ERRORS.SOMETHING_WENT_WRONG.replace('{{error}}', JSON.stringify(e, null, 2)) 12 | } 13 | // log 14 | logger(errorMessage) 15 | // return error response 16 | return new ExecutableGameFunctionResponse(ExecutableGameFunctionStatus.Failed, errorMessage) 17 | } 18 | 19 | export const formatNumber = (num: string | number, decimalPlaces?: number): string => { 20 | return Number(num).toLocaleString(undefined, { 21 | style: 'decimal', 22 | minimumFractionDigits: 0, 23 | maximumFractionDigits: decimalPlaces || 8, 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/__test__/mocks/gameAgent.mock.ts: -------------------------------------------------------------------------------- 1 | // Mock for GameAgent and related classes 2 | import { GameWorker, GameFunction } from '@virtuals-protocol/game'; 3 | 4 | // Mock for GameAgent 5 | export const mockGameAgent = { 6 | init: jest.fn().mockResolvedValue(undefined), 7 | step: jest.fn().mockResolvedValue(undefined), 8 | setLogger: jest.fn(), 9 | name: 'Mock Agent', 10 | }; 11 | 12 | // Helper to create a mock GameWorker 13 | export const createMockGameWorker = (id: string, functions: GameFunction[]) => { 14 | const mockWorker = new GameWorker({ 15 | id, 16 | name: `Mock Worker ${id}`, 17 | description: 'Mock worker for testing', 18 | functions, 19 | }); 20 | 21 | // Spy on methods 22 | jest.spyOn(mockWorker, 'getEnvironment'); 23 | 24 | return mockWorker; 25 | }; 26 | 27 | // Reset all mocks 28 | export const resetGameAgentMocks = () => { 29 | mockGameAgent.init.mockClear(); 30 | mockGameAgent.step.mockClear(); 31 | mockGameAgent.setLogger.mockClear(); 32 | }; 33 | -------------------------------------------------------------------------------- /plugins/recallStoragePlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-recall-storage-plugin", 3 | "version": "0.1.0", 4 | "description": "", 5 | "type": "module", 6 | "main": "./dist/index.js", 7 | "module": "./dist/index.mjs", 8 | "types": "./dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 12 | }, 13 | "author": "", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "dotenv": "^16.4.7", 17 | "tempy": "^3.1.0", 18 | "ts-node-dev": "^2.0.0", 19 | "tsup": "^8.3.5", 20 | "typescript": "^5.7.2" 21 | }, 22 | "dependencies": { 23 | "@recallnet/chains": "^0.0.6", 24 | "@recallnet/sdk": "^0.0.7", 25 | "@virtuals-protocol/game": "^0.1.9", 26 | "viem": "^2.23.10" 27 | }, 28 | "files": [ 29 | "dist" 30 | ], 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/game-by-virtuals/game-node" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-dpsn-plugin", 3 | "version": "1.0.0", 4 | "description": "DPSN plugin for Virtuals Protocol Game Node", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "jest --coverage", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@types/jest": "^29.5.14", 16 | "@types/node": "^22.10.3", 17 | "@typescript-eslint/eslint-plugin": "^8.19.1", 18 | "@typescript-eslint/parser": "^8.19.1", 19 | "eslint": "^9.17.0", 20 | "jest": "^29.7.0", 21 | "ts-jest": "^29.2.5", 22 | "ts-node": "^10.9.2", 23 | "ts-node-dev": "^2.0.0", 24 | "tsup": "^8.3.5", 25 | "typescript": "^5.7.3" 26 | }, 27 | "dependencies": { 28 | "@virtuals-protocol/game": "^0.1.7", 29 | "dpsn-client": "^1.0.9" 30 | }, 31 | "files": [ 32 | "dist" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /plugins/stateofmikaPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-state-mika-plugin", 3 | "version": "0.1.0", 4 | "description": "State of Mika Plugin for Virtuals GAME", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "build": "tsup src/index.ts --dts --format cjs,esm --out-dir dist", 10 | "test": "jest --coverage" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2", 17 | "@types/jest": "^29.5.14", 18 | "jest": "^29.7.0", 19 | "ts-jest": "^29.2.5" 20 | }, 21 | "dependencies": { 22 | "tsup": "^8.3.5", 23 | "axios": "^0.27.2", 24 | "@virtuals-protocol/game": "^0.1.7" 25 | }, 26 | "files": [ 27 | "dist" 28 | ], 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/game-by-virtuals/game-node" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025, Virtuals Protocol 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /game-starter/src/agent.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent, LLMModel } from "@virtuals-protocol/game"; 2 | import { activityRecommenderWorker } from "./worker"; 3 | import dotenv from "dotenv"; 4 | dotenv.config(); 5 | 6 | if (!process.env.API_KEY) { 7 | throw new Error('API_KEY is required in environment variables'); 8 | } 9 | 10 | export const activity_agent = new GameAgent(process.env.API_KEY, { 11 | name: "Activity Recommender", 12 | goal: "Help users find the perfect activities based on their location and current weather conditions", 13 | description: "You are an agent that gets location of the user and then uses that to get weather information and then uses that to recommend activities", 14 | workers: [activityRecommenderWorker], 15 | llmModel: LLMModel.DeepSeek_R1 // this is an optional paramenter to set the llm model for the agent. Default is Llama_3_1_405B_Instruct 16 | }); 17 | 18 | activity_agent.setLogger((agent: GameAgent, msg: string) => { 19 | console.log(`🎯 [${agent.name}]`); 20 | console.log(msg); 21 | console.log("------------------------\n"); 22 | }); -------------------------------------------------------------------------------- /plugins/discordPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-discord-plugin", 3 | "version": "0.1.4", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "jest --coverage", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@types/jest": "^29.5.14", 16 | "@types/node": "^22.10.3", 17 | "@typescript-eslint/eslint-plugin": "^8.19.1", 18 | "@typescript-eslint/parser": "^8.19.1", 19 | "eslint": "^9.17.0", 20 | "typescript": "^5.7.2", 21 | "jest": "^29.7.0", 22 | "ts-jest": "^29.2.5", 23 | "ts-node": "^10.9.2", 24 | "ts-node-dev": "^2.0.0" 25 | }, 26 | "dependencies": { 27 | "@virtuals-protocol/game": "^0.1.7", 28 | "discord.js": "^14.17.3", 29 | "tsup": "^8.3.5" 30 | }, 31 | "files": [ 32 | "dist" 33 | ], 34 | "repository": { 35 | "type": "git", 36 | "url": "https://github.com/game-by-virtuals/game-node" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/plugin_metadata.yml: -------------------------------------------------------------------------------- 1 | plugin_name: "Token Metrics Virtuals Plugin" 2 | author: "Token Metrics Engineering Team" 3 | logo_url: "" 4 | release_date: "2025-09" 5 | 6 | short_description: "Complete Token Metrics integration plugin for Virtuals Protocol GAME framework providing AI-powered cryptocurrency analysis with comprehensive API endpoints" 7 | detailed_description: "A comprehensive plugin that integrates Token Metrics' AI-powered cryptocurrency analysis platform with the Virtuals Protocol GAME framework. Provides API endpoints covering token discovery, moonshot analysis, trading signals, market metrics, AI reports, technical analysis, and crypto indices. Features include real-time pricing data, AI-generated trading recommendations, sentiment analysis, and quantitative metrics for informed crypto trading decisions." 8 | 9 | plugin_logo_url: "" 10 | screenshots: 11 | - "" 12 | - "" 13 | demo_video_url: "" 14 | documentation_url: "https://developers.tokenmetrics.com/" 15 | changelog_url: "" 16 | 17 | x_account_handle: "@tokenmetricsinc" 18 | support_contact: "support@tokenmetrics.com" 19 | community_url: "" 20 | -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-on-chain-actions-plugin", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "ts-node-dev": "^2.0.0", 16 | "typescript": "^5.7.2" 17 | }, 18 | "dependencies": { 19 | "@goat-sdk/core": "0.4.6", 20 | "@goat-sdk/plugin-erc20": "0.2.8", 21 | "@goat-sdk/plugin-uniswap": "0.2.9", 22 | "@goat-sdk/wallet-evm": "0.2.6", 23 | "@goat-sdk/wallet-viem": "0.2.6", 24 | "@virtuals-protocol/game": "^0.1.4", 25 | "ajv": "8.17.1", 26 | "tsup": "^8.3.5", 27 | "zod": "3.23.8", 28 | "zod-to-json-schema": "^3.24.1" 29 | }, 30 | "files": [ 31 | "dist" 32 | ], 33 | "repository": { 34 | "type": "git", 35 | "url": "https://github.com/game-by-virtuals/game-node" 36 | } 37 | } -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-desk-exchange-plugin", 3 | "version": "1.0.0", 4 | "description": "DESK Exchange Plugin for ...", 5 | "main": "dist/index.js", 6 | "dependencies": { 7 | "@virtuals-protocol/game": "^0.1.7" 8 | }, 9 | "devDependencies": { 10 | "@desk-exchange/typescript-sdk": "1.0.3", 11 | "@eslint/js": "9.15.0", 12 | "@jest/globals": "29.7.0", 13 | "@types/jest": "29.5.14", 14 | "@types/node": "20.0.0", 15 | "eslint": "9.15.0", 16 | "eslint-config-prettier": "9.1.0", 17 | "eslint-plugin-import": "2.31.0", 18 | "eslint-plugin-prettier": "5.2.1", 19 | "eslint-plugin-simple-import-sort": "12.1.1", 20 | "jest": "29.7.0", 21 | "ts-jest": "29.2.5", 22 | "tsup": "8.3.5", 23 | "typescript-eslint": "8.16.0" 24 | }, 25 | "scripts": { 26 | "build": "tsup --format esm --dts", 27 | "dev": "tsup --watch --format esm --dts", 28 | "lint": "eslint . --config eslint.config.mjs", 29 | "test": "jest --coverage" 30 | } 31 | } -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/src/constants.ts: -------------------------------------------------------------------------------- 1 | export enum GAME_WORKER_FUNCTION_NAME { 2 | GET_ACCOUNT_SUMMARY = 'get_account_summary', 3 | CANCEL_ORDERS = 'cancel_orders', 4 | PERP_TRADE = 'perp_trade', 5 | } 6 | 7 | export const GAME_WORKER_FUNCTIONS: Array = Object.values(GAME_WORKER_FUNCTION_NAME) 8 | 9 | export enum FMT_ERRORS { 10 | SOMETHING_WENT_WRONG = 'Something went wrong: {{error}}', 11 | FAILED_TO_GET_ACCOUNT_SUMMARY = 'Failed to get account summary: {{error}}', 12 | FAILED_TO_CANCEL_ORDERS = 'Failed to cancel orders: {{error}}', 13 | FAILED_TO_PERP_TRADE = 'Failed to perp trade: {{error}}', 14 | } 15 | 16 | // NOTE: these messages are used in the feedback of the executable game function 17 | // also use to compare in tests 18 | export enum SUCCESS_MESSAGES { 19 | // get account summary 20 | ACCOUNT_SUMMARY = 'Here is the summary of your account:', 21 | YOUR_POSITIONS = 'Your positions:', 22 | YOUR_ORDERS = 'Your orders:', 23 | YOUR_COLLATERALS = 'Your collaterals:', 24 | // cancel orders 25 | ORDER_CANCELLED = 'Successfully cancelled:', 26 | // perp trade 27 | PERP_TRADE = 'Successfully placed', 28 | } 29 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "Fetch the coin data of Bitcoin.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [coingeckoMAOPPlugin.getWorker({})], 21 | }); 22 | 23 | (async () => { 24 | agent.setLogger((agent, message) => { 25 | console.log(`-----[${agent.name}]-----`); 26 | console.log(message); 27 | console.log("\n"); 28 | }); 29 | 30 | await agent.init(); 31 | 32 | while (true) { 33 | await agent.step({ 34 | verbose: true, 35 | }); 36 | } 37 | })(); 38 | -------------------------------------------------------------------------------- /plugins/imageGenPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: './.env' }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import ImageGenPlugin from "."; 6 | 7 | const imageGenPlugin = new ImageGenPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.TOGETHER_API_KEY, // Default key: UP-17f415babba7482cb4b446a1 10 | }, 11 | }); 12 | 13 | // Create an agent with the worker 14 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 15 | name: "Image Generation Worker", 16 | goal: "Generate an anime-style character image with Twitter logo.", 17 | description: "You are an AI agent specialized in generating images. You can create images based on text prompts using Together AI's FLUX schnell model.", 18 | workers: [ 19 | imageGenPlugin.getWorker({}), 20 | ], 21 | }); 22 | 23 | (async () => { 24 | agent.setLogger((agent, message) => { 25 | console.log(`-----[${agent.name}]-----`); 26 | console.log(message); 27 | console.log("\n"); 28 | }); 29 | 30 | await agent.init(); 31 | 32 | while (true) { 33 | await agent.step({ 34 | verbose: true, 35 | }); 36 | } 37 | })(); -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Token Metrics 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /plugins/alchemyPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-alchemy-plugin", 3 | "version": "0.1.0", 4 | "description": "A plugin for Virtuals Protocol G.A.M.E. to fetch on-chain data using the Alchemy API.", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "jest --coverage", 10 | "tsup": "tsup src/example.ts --dts --format cjs,esm --out-dir dist", 11 | "build": "npm run tsup" 12 | }, 13 | "author": "Alchemy", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "@types/jest": "^29.5.14", 17 | "@types/node": "^22.10.3", 18 | "@typescript-eslint/eslint-plugin": "^8.19.1", 19 | "@typescript-eslint/parser": "^8.19.1", 20 | "eslint": "^9.17.0", 21 | "jest": "^29.7.0", 22 | "ts-jest": "^29.2.5", 23 | "ts-node": "^10.9.2", 24 | "ts-node-dev": "^2.0.0", 25 | "tsup": "^8.3.5", 26 | "typescript": "^5.7.3" 27 | }, 28 | "dependencies": { 29 | "@virtuals-protocol/game": "^0.1.7", 30 | "axios": "^1.7.7" 31 | }, 32 | "files": [ 33 | "dist" 34 | ], 35 | "repository": { 36 | "type": "git" 37 | } 38 | } -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/plugin.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | One-liner – What does this plugin contribution add or change? 4 | 5 | ## Links 6 | 7 | - Plugin documentation: 8 | - Issue link (if applicable): 9 | - Other useful links: 10 | 11 | ## Plugin Documentation Checklist 12 | 13 | - README Validation 14 | - [ ] `README.md` file exists in the plugin root folder 15 | - [ ] Clear installation instructions 16 | - [ ] Usage examples with code snippets 17 | - [ ] List of features and capabilities 18 | - [ ] Troubleshooting guide (if applicable) 19 | - [ ] Contribution guidelines (if applicable) 20 | 21 | - Metadata Validation 22 | - [ ] `plugin_metadata.yml` file exists in the plugin root folder 23 | - [ ] Complete metadata provided in reference to [plugin metadata template](../.././plugins/plugin_metadata_template.yml) 24 | 25 | ## Dev Testing 26 | 27 | (Include where applicable) 28 | 29 | - Screenshots/GIFs 30 | - Video Demonstrations 31 | - Logs or Console Outputs 32 | - Testing steps for the plugin 33 | 34 | ## Additional Notes 35 | 36 | - Any considerations for future updates or enhancements. 37 | - Known issues or limitations with this plugin contribution. 38 | -------------------------------------------------------------------------------- /plugins/alchemyPlugin/plugin_metadata.yml: -------------------------------------------------------------------------------- 1 | # General Information 2 | plugin_name: "Alchemy Plugin" 3 | author: "Alchemy" 4 | logo_url: "https://bit.ly/alchemy-logo" 5 | release_date: "2025-04" 6 | 7 | # Description 8 | short_description: "The Alchemy Plugin provides a set of functions to retrieve on-chain data from the Alchemy API giving your agent the power to work with web3 data." # One-liner description for listings 9 | detailed_description: "The Alchemy Plugin provides a set of functions to retrieve on-chain data from the Alchemy API giving your agent the power to work with web3 data. With this plugin, you can fetch portfolio data—including transaction history, token details, NFT information, and NFT contracts—by querying wallet addresses across various supported networks." # Full description with features and benefits 10 | 11 | # Media & Assets 12 | plugin_logo_url: "https://bit.ly/alchemy-logo" 13 | screenshots: 14 | - "" 15 | - "" 16 | demo_video_url: "" 17 | documentation_url: "" 18 | changelog_url: "" 19 | 20 | # Contact & Support 21 | x_account_handle: "@Alchemy" 22 | support_contact: "https://www.alchemy.com/support" 23 | community_url: "https://alchemy.com/discord" -------------------------------------------------------------------------------- /plugins/echochambersPlugin/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Savage | x.com/savageapi | t.me/savagejay 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /plugins/rss3Plugin/src/example.ts: -------------------------------------------------------------------------------- 1 | 2 | import { GameAgent } from "@virtuals-protocol/game"; 3 | import RSS3Plugin from "."; 4 | 5 | 6 | const rss3Plugin = new RSS3Plugin({ 7 | credentials: { 8 | apiKey: process.env.RSS3_API_KEY ?? "", // RSS3 API Key is currently optional 9 | }, 10 | }); 11 | 12 | 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "RSS3 Worker", 15 | goal: "Retrieve account activities via the RSS3 Network.", 16 | description: `You are an AI agent with the ability to access real-time activities via the RSS3 Network. You take in a blockchain wallet address (beginning with 0x) or an ENS domain (ending with .eth) and retrieve the activities associated with the account. 17 | `, 18 | workers: [ 19 | rss3Plugin.getWorker({ 20 | functions: [ 21 | rss3Plugin.getActivitiesFunction, 22 | ], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.hourlyTradingSignals.ts: -------------------------------------------------------------------------------- 1 | import TokenMetricsPlugin from "../index"; 2 | 3 | async function main() { 4 | const plugin = new TokenMetricsPlugin({ 5 | apiClientConfig: { 6 | apiKey: process.env.TOKENMETRICS_API_KEY!, 7 | baseApiUrl: "https://api.tokenmetrics.com/v2", 8 | }, 9 | }); 10 | 11 | const worker = plugin.getWorker(); 12 | 13 | console.log("🚀 Testing Hourly Trading Signals endpoint...\n"); 14 | 15 | try { 16 | // Test hourly trading signals with default parameters 17 | console.log("📊 Getting hourly trading signals..."); 18 | const result = await worker.functions 19 | .find(f => f.name === "get_hourly_trading_signals") 20 | ?.executable( 21 | { 22 | limit: "10", 23 | page: "1" 24 | }, 25 | console.log 26 | ); 27 | 28 | if (result?.status === 'done') { 29 | console.log("\n✅ Hourly trading signals retrieved successfully!"); 30 | } else { 31 | console.log("\n❌ Failed to get hourly trading signals:", result?.feedback); 32 | } 33 | 34 | } catch (error) { 35 | console.error("❌ Error:", error); 36 | } 37 | } 38 | 39 | main().catch(console.error); 40 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.coinDataByID.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "Fetch the coin data of Bitcoin.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.coinDataByID], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/telegramPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-telegram-plugin", 3 | "version": "0.1.4", 4 | "description": "", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "jest --coverage", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@types/jest": "^29.5.14", 16 | "@types/jsonwebtoken": "^9.0.7", 17 | "@types/node": "^22.10.3", 18 | "@types/node-telegram-bot-api": "^0.64.7", 19 | "@typescript-eslint/eslint-plugin": "^8.19.1", 20 | "@typescript-eslint/parser": "^8.19.1", 21 | "eslint": "^9.17.0", 22 | "jest": "^29.7.0", 23 | "ts-jest": "^29.2.5", 24 | "ts-node": "^10.9.2", 25 | "ts-node-dev": "^2.0.0", 26 | "tsup": "^8.3.5", 27 | "typescript": "^5.7.3" 28 | }, 29 | "dependencies": { 30 | "@virtuals-protocol/game": "^0.1.7", 31 | "node-telegram-bot-api": "^0.66.0", 32 | "tsup": "^8.3.5" 33 | }, 34 | "files": [ 35 | "dist" 36 | ], 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/game-by-virtuals/game-node" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.coinsCategoriesList.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "list coin categories.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.coinsCategoriesList], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.coinPricesByIDs.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "Fetch the coin price of Bitcoin.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.coinPricesByIDs], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.trendingSearchList.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find trending search list.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.trendingSearchList], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.trendingPoolsList.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find trending pools list, include 'base_token'.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.trendingPoolsList], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.newPoolsByNetwork.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find new pools on network 'eth', include base_token.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.newPoolsByNetwork], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/plugin_metadata_template.yml: -------------------------------------------------------------------------------- 1 | # General Information 2 | plugin_name: "" # Name of the plugin 3 | author: "" # Author and team name 4 | logo_url: "" # URL to the author photo or team logo (512x512 recommended) (if any) 5 | release_date: "" # Release date (YYYY-MM) 6 | 7 | # Description 8 | short_description: "" # One-liner description for listings 9 | detailed_description: "" # Full description with features and benefits 10 | 11 | # Media & Assets 12 | plugin_logo_url: "" # URL to the plugin logo (512x512 recommended) (if any or fallback to logo_url) 13 | screenshots: # List of screenshots showcasing the plugin (if any) 14 | - "" # e.g., "https://example.com/screenshot1.png" 15 | - "" 16 | demo_video_url: "" # Link to a demo or walkthrough video (if any) 17 | documentation_url: "" # Link to the plugin's official documentation (if any) 18 | changelog_url: "" # Link to the changelog (if maintained) 19 | 20 | # Contact & Support 21 | x_account_handle: "" # X (formerly known as Twitter) account handle (ie: @GAME_Virtuals) 22 | support_contact: "" # Email or Slack/Discord link for user support 23 | community_url: "" # Forum or community link (if any) 24 | -------------------------------------------------------------------------------- /plugins/alchemyPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game"; 2 | import AlchemyPlugin from "./alchemyPlugin"; 3 | import dotenv from "dotenv"; 4 | dotenv.config(); 5 | 6 | // Add your Alchemy API key to the .env file 7 | const alchemyPlugin = new AlchemyPlugin({ 8 | credentials: { 9 | apiKey: process.env.ALCHEMY_API_KEY || "", 10 | }, 11 | }); 12 | 13 | /** 14 | * Create an agent to fetch on-chain data using the Alchemy API 15 | * In this example, the agent fetches the nfts owned by 0xe5cB067E90D5Cd1F8052B83562Ae670bA4A211a8 on eth mainnet 16 | * Add your Virtuals Protocol API token to the .env file 17 | */ 18 | const alchemyAgent = new GameAgent(process.env.VIRTUALS_API_TOKEN || "", { 19 | name: "Alchemy Agent", 20 | goal: "Fetch the nfts owned by 0xe5cB067E90D5Cd1F8052B83562Ae670bA4A211a8 on eth mainnet", 21 | description: "An agent that can fetch on-chain data using the Alchemy API including transaction history, tokens held (with metadata/prices), token balances, NFTs by wallet, and NFT contracts by wallet.", 22 | workers: [ 23 | alchemyPlugin.getWorker(), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | // Initialize the agent 29 | await alchemyAgent.init(); 30 | await alchemyAgent.run(10, {verbose: true}); 31 | })(); -------------------------------------------------------------------------------- /tools/cloud-to-sdk/generateWorker.ts: -------------------------------------------------------------------------------- 1 | // generateWorker.ts 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import { PluginJson } from './types'; 5 | 6 | export function generateWorker(json: PluginJson, outputPath: string): void { 7 | try { 8 | const dir = path.dirname(outputPath); 9 | if (!fs.existsSync(dir)) { 10 | fs.mkdirSync(dir, { recursive: true }); 11 | } 12 | 13 | if (!json.workers?.length) { 14 | throw new Error('No worker configuration found in JSON'); 15 | } 16 | 17 | const workersContent = json.workers.map(worker => ` 18 | new GameWorker({ 19 | id: "${worker.id}", 20 | name: "${worker.name}", 21 | description: \`${worker.description}\`, 22 | functions: functions["${worker.workerId}"] || [] 23 | })`).join(',\n'); 24 | 25 | const content = ` 26 | import { GameWorker } from "@virtuals-protocol/game"; 27 | import { functions } from "./functions"; 28 | 29 | export const workers = [${workersContent} 30 | ];`; 31 | 32 | fs.writeFileSync(outputPath, content); 33 | console.log(`✅ Generated worker.ts at ${outputPath}`); 34 | } catch (error) { 35 | console.error(`❌ Error generating worker.ts:`, error); 36 | throw error; 37 | } 38 | } -------------------------------------------------------------------------------- /plugins/echochambersPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-echochambers-plugin", 3 | "version": "0.1.0", 4 | "main": "./dist/index.js", 5 | "module": "./dist/index.mjs", 6 | "types": "./dist/index.d.ts", 7 | "license": "MIT", 8 | "author": { 9 | "name": "SavageOps", 10 | "url": "https://x.com/savageapi" 11 | }, 12 | "scripts": { 13 | "build": "tsup src/index.ts --format cjs,esm --dts", 14 | "dev": "tsup src/index.ts --format cjs,esm --dts --watch", 15 | "example": "ts-node src/example.ts", 16 | "example:mock": "ts-node src/example_mock.ts", 17 | "example:2": "ts-node src/example_2.ts", 18 | "example:dev": "nodemon --exec ts-node src/example.ts", 19 | "example:2:dev": "nodemon --exec ts-node src/example_2.ts", 20 | "prepublish": "npm run build" 21 | }, 22 | "dependencies": { 23 | "@virtuals-protocol/game": "^0.1.4", 24 | "axios": "^1.6.5" 25 | }, 26 | "devDependencies": { 27 | "typescript": "^5.3.3", 28 | "tsup": "^8.0.1", 29 | "ts-node": "^10.9.2", 30 | "nodemon": "^3.0.2" 31 | }, 32 | "peerDependencies": { 33 | "@virtuals-protocol/game": "^0.1.4" 34 | }, 35 | "keywords": [ 36 | "virtuals", 37 | "game", 38 | "protocol", 39 | "echochambers", 40 | "plugin" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.coinsListWithMarketData.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find bitcoin info with market data, use usd as standard currency.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.coinsListWithMarketData], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.tokenInfoByAddress.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find token info on address '0xdac17f958d2ee523a2206206994597c13d831ec7' on network 'eth'.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.tokenInfoByAddress], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.trendingPoolsByNetwork.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find a page of last 24h trending pools on network 'eth', include 'base_token'.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.trendingPoolsByNetwork], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.topGainersLosersConfig.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find top gainers and losers of last 24h, use 'usd' as currency, limit 1000 top coins .", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.topGainersLosersConfig], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.coinPricesByAddress.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "Fetch the coin price by address: 0x2260fac5e5542a773aa44fbcfedf7c193bc2c599 on ethereum platform.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.coinPricesByAddress], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.tokenPriceByAddresses.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find token price on address '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' on network 'eth'.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.tokenPriceByAddresses], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/plugin_metadata.yml: -------------------------------------------------------------------------------- 1 | # General Information 2 | plugin_name: 'game-dpsn-plugin' # Name of the plugin 3 | author: 'DPSN-Tech-Team' # Author and team name 4 | logo_url: 'https://pbs.twimg.com/profile_images/1832068773064355840/tUbNKURh_400x400.jpg' # URL to the author photo or team logo (512x512 recommended) (if any) 5 | release_date: 2025-04 # Release date (YYYY-MM) 6 | 7 | # Description 8 | short_description: 'DPSN plugin to subscribe to dpsn data streams for Virtuals Protocol agents' # One-liner description for listings 9 | detailed_description: 'This plugin allows Virtuals Protocol agents to connect to and interact with real-time data streams from the DPSN Data Streams Store. Agents can use it for decision-making and event handling. Developers can also publish custom streams using the dpsn-client-nodejs library on npmjs.' 10 | 11 | # Media & Assets 12 | plugin_logo_url: 'https://pbs.twimg.com/profile_images/1832068773064355840/tUbNKURh_400x400.jpg' # URL to the plugin logo (512x512 recommended) (if any or fallback to logo_url) 13 | 14 | # Contact & Support 15 | x_account_handle: '@DPSN_org' # X (formerly known as Twitter) account handle (ie: @GAME_Virtuals) 16 | support_contact: 'sanil@dpsn.org' # Email or Slack/Discord link for user support 17 | community_url: 'https://t.me/dpsn_dev' # Forum or community link (if any) 18 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/example.specificPoolData.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | 4 | import { GameAgent } from "@virtuals-protocol/game"; 5 | import CoingeckoMAOPPlugin from "."; 6 | 7 | const coingeckoMAOPPlugin = new CoingeckoMAOPPlugin({ 8 | apiClientConfig: { 9 | apiKey: process.env.MAOP_GAME_PLUGIN_API_KEY, 10 | baseApiUrl: process.env.MAOP_ENDPOINT, 11 | }, 12 | }); 13 | 14 | // Create an agent with the worker 15 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 16 | name: "Cryptocurrency Data Worker", 17 | goal: "find pool address '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640' on network 'eth', include 'base_token,quote_token'.", 18 | description: 19 | "You are an AI agent specialized in fetching cryptocurrency data. You can retrieve current market data using the Coingecko API.", 20 | workers: [ 21 | coingeckoMAOPPlugin.getWorker({ 22 | functions: [coingeckoMAOPPlugin.specificPoolData], 23 | }), 24 | ], 25 | }); 26 | 27 | (async () => { 28 | agent.setLogger((agent, message) => { 29 | console.log(`-----[${agent.name}]-----`); 30 | console.log(message); 31 | console.log("\n"); 32 | }); 33 | 34 | await agent.init(); 35 | 36 | while (true) { 37 | await agent.step({ 38 | verbose: true, 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.priceData.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get real-time price data 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Price Data Agent", 15 | goal: "Get real-time cryptocurrency prices based on token IDs for current market valuation.", 16 | description: 17 | "You are an AI agent specialized in retrieving real-time cryptocurrency price data using TokenMetrics. You provide current market prices, market capitalizations, and pricing information for specified cryptocurrencies using their token IDs.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getPriceData], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.dailyOhlcv.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get daily OHLCV data 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Daily OHLCV Analyst", 15 | goal: "Get daily OHLCV (Open, High, Low, Close, Volume) data for long-term technical analysis and trend identification.", 16 | description: 17 | "You are an AI agent specialized in providing daily cryptocurrency price and volume data using TokenMetrics. You deliver OHLCV data perfect for longer-term technical analysis, trend identification, and swing trading strategies.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getDailyOhlcv], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.hourlyOhlcv.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get hourly OHLCV data 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Hourly OHLCV Analyst", 15 | goal: "Get hourly OHLCV (Open, High, Low, Close, Volume) data for detailed technical analysis and short-term trading patterns.", 16 | description: 17 | "You are an AI agent specialized in providing hourly cryptocurrency price and volume data using TokenMetrics. You deliver OHLCV data essential for technical analysis, chart patterns, and intraday trading strategies.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getHourlyOhlcv], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.tokenmetricsAi.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to chat with TokenMetrics AI 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics AI Chat Agent", 15 | goal: "Chat with TokenMetrics AI to get insights about cryptocurrency markets, trading strategies, and investment advice.", 16 | description: 17 | "You are an AI agent that can interact with TokenMetrics AI to get expert cryptocurrency insights. You can ask questions about market trends, trading strategies, investment opportunities, and get AI-powered analysis of the crypto market.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getTokenMetricsAi], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.topMarketCap.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get top market cap cryptocurrencies 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Top Market Cap Agent", 15 | goal: "Get the list of top cryptocurrencies by market capitalization to identify the most valuable and established digital assets.", 16 | description: 17 | "You are an AI agent specialized in identifying leading cryptocurrencies by market capitalization using TokenMetrics data. You provide information about the most valuable and established digital assets in the crypto market.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getTopMarketCapTokens], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.tradingSignals.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get AI-generated trading signals 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Trading Signals Agent", 15 | goal: "Get AI-generated trading signals for long and short positions to identify optimal buy and sell opportunities.", 16 | description: 17 | "You are an AI agent specialized in providing AI-generated trading signals using TokenMetrics algorithms. You analyze market conditions to provide bullish (1), bearish (-1), or neutral (0) signals with strength indicators for cryptocurrencies.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getTradingSignals], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.aiReports.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get AI-generated reports 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics AI Research Agent", 15 | goal: "Retrieve comprehensive AI-generated reports providing deep dives, investment analyses, and code reviews for cryptocurrencies.", 16 | description: 17 | "You are an AI agent specialized in delivering comprehensive AI-generated cryptocurrency research reports using TokenMetrics. You provide deep analytical reports, investment analyses, technical assessments, and code reviews to support informed decision-making.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getAiReports], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.marketMetrics.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get market analytics and indicators 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Market Analytics Agent", 15 | goal: "Get comprehensive market analytics including bullish/bearish indicators to understand overall crypto market conditions.", 16 | description: 17 | "You are an AI agent specialized in analyzing overall cryptocurrency market conditions using TokenMetrics market analytics. You provide insights into market sentiment, trend analysis, and macro indicators to help understand the broader crypto market environment.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getMarketMetrics], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.quantmetrics.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get quantitative metrics 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Quantitative Analyst", 15 | goal: "Get advanced quantitative metrics and statistical analysis for cryptocurrency tokens to support data-driven investment decisions.", 16 | description: 17 | "You are an AI agent specialized in quantitative cryptocurrency analysis using TokenMetrics advanced mathematical models. You provide statistical metrics, quantitative indicators, and mathematical analysis to support sophisticated trading and investment strategies.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getQuantmetrics], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.sentiments.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get market sentiment analysis 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Sentiment Analysis Agent", 15 | goal: "Get hourly sentiment scores from Twitter, Reddit, and news sources to understand market sentiment and social media trends.", 16 | description: 17 | "You are an AI agent specialized in analyzing cryptocurrency market sentiment. You can retrieve hourly sentiment scores from social media platforms (Twitter, Reddit) and news sources, providing insights into market psychology and social trends that influence crypto prices.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getSentiments], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.resistanceSupport.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get resistance and support levels 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Technical Levels Agent", 15 | goal: "Get historical resistance and support levels for cryptocurrencies to identify key technical price levels for trading decisions.", 16 | description: 17 | "You are an AI agent specialized in technical analysis using TokenMetrics resistance and support level data. You identify critical price levels where cryptocurrencies historically find support or face resistance, essential for technical trading strategies.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getResistanceSupport], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.correlation.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get token correlation analysis 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Correlation Analysis Agent", 15 | goal: "Get correlation analysis showing the top 10 and bottom 10 correlations of tokens with the top 100 market cap cryptocurrencies.", 16 | description: 17 | "You are an AI agent specialized in cryptocurrency correlation analysis. You can analyze how different tokens move in relation to each other, providing insights for portfolio diversification, risk management, and understanding market relationships between cryptocurrencies.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getCorrelation], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.cryptoInvestors.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get crypto investor insights 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Crypto Investor Intelligence Agent", 15 | goal: "Get insights into crypto investors and their activity scores to understand institutional and whale investor behavior.", 16 | description: 17 | "You are an AI agent specialized in analyzing cryptocurrency investor behavior using TokenMetrics investor intelligence. You provide insights into institutional investors, whale activities, and investor sentiment to help understand market dynamics from an investor perspective.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getCryptoInvestors], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.scenarioAnalysis.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get scenario-based price predictions 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Scenario Analysis Agent", 15 | goal: "Get price predictions based on different cryptocurrency market scenarios including bullish, bearish, and neutral conditions.", 16 | description: 17 | "You are an AI agent specialized in cryptocurrency scenario analysis and price forecasting. You can provide price predictions for different market scenarios, helping users understand potential price movements under various market conditions and make informed investment decisions.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getScenarioAnalysis], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { EnsoClient } from "@ensofinance/sdk"; 2 | 3 | type Route = Awaited>["route"]; 4 | 5 | // The buildRoutePath will return string as follows: 6 | // 7 | //"Split via enso 8 | // Internal Routes: 9 | // Route 1: 10 | // Swap via enso 11 | // Route 2: 12 | // Swap via enso 13 | // Deposit via stakestone-stone 14 | // Deposit via uniswap-v2" 15 | 16 | /** 17 | * Build a route path string from Enso route 18 | * @returns string 19 | */ 20 | export function buildRoutePath(route: Route): string { 21 | let str = ""; 22 | 23 | function buildStep(step: Route[number], indent: string = ""): string { 24 | const action = capitalizeWord(step.action); 25 | let stepStr = `${indent}${action} via ${step.protocol}\n`; 26 | 27 | if (step.internalRoutes) { 28 | stepStr += `${indent} Internal Routes:\n`; 29 | step.internalRoutes.forEach((internalRoute, index) => { 30 | stepStr += `${indent} Route ${index + 1}:\n`; 31 | internalRoute.forEach((internalStep) => { 32 | stepStr += buildStep(internalStep, `${indent} `); 33 | }); 34 | }); 35 | } 36 | 37 | return stepStr; 38 | } 39 | 40 | route.forEach((step) => { 41 | str += buildStep(step); 42 | }); 43 | 44 | return str.trim(); // Trim to remove the last newline 45 | } 46 | 47 | function capitalizeWord(word: string) { 48 | return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); 49 | } 50 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.tmGrade.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get TM Grade insights for tokens 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics TM Grade Analyst", 15 | goal: "Get the latest TM Grade for tokens, including trader grade change, quant grade, signals, momentum, and 24-hour percentage changes for both TM Grade and Trader Grade.", 16 | description: 17 | "You are an AI agent specialized in analyzing TokenMetrics (TM) Grade insights for cryptocurrencies. You provide comprehensive analysis of TM grades, trader grade changes, quantitative metrics, trading signals, and momentum indicators to help users make informed trading and investment decisions.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getTmGrade], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.moonshotTokens.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get moonshot tokens for high-potential trading opportunities 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Moonshot Analyst", 15 | goal: "Get AI-curated token picks (Moonshots) with high breakout potential based on grades, sentiment, volume, and on-chain data to help users trade smarter and faster.", 16 | description: 17 | "You are an AI agent specialized in identifying high-potential cryptocurrency moonshots using TokenMetrics AI analysis. You help users discover tokens with strong breakout potential based on comprehensive analysis of grades, sentiment, volume, and on-chain data.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getMoonshotTokens], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.technologyGrade.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get technology grade insights for tokens 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Technology Grade Analyst", 15 | goal: "Get Technology Grade insights for tokens, including activity score, security score, repository score, collaboration score, and DeFi scanner score.", 16 | description: 17 | "You are an AI agent specialized in analyzing cryptocurrency technology quality using TokenMetrics Technology Grade insights. You evaluate technical aspects including development activity, security measures, code quality, collaboration patterns, and DeFi integration to assess the technological strength of crypto projects.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getTechnologyGrade], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/__test__/mocks/dpsnClient.mock.ts: -------------------------------------------------------------------------------- 1 | // Mock for DpsnClient 2 | const mockDpsnClient = { 3 | init: jest.fn().mockResolvedValue(undefined), 4 | subscribe: jest.fn().mockImplementation((topic, handler) => { 5 | // Store the handler for later use in tests 6 | mockDpsnClient.subscriptionHandlers[topic] = handler; 7 | return Promise.resolve(); 8 | }), 9 | unsubscribe: jest.fn().mockImplementation((topic) => { 10 | // Remove the handler for the topic 11 | delete mockDpsnClient.subscriptionHandlers[topic]; 12 | return Promise.resolve(); 13 | }), 14 | disconnect: jest.fn().mockResolvedValue(undefined), 15 | setBlockchainConfig: jest.fn(), 16 | 17 | // Helper properties for testing 18 | subscriptionHandlers: {} as Record< 19 | string, 20 | (topic: string, message: any) => void 21 | >, 22 | 23 | // Helper method to simulate receiving a message 24 | simulateMessage: (topic: string, message: any) => { 25 | const handler = mockDpsnClient.subscriptionHandlers[topic]; 26 | if (handler) { 27 | // Call the handler with topic and message as separate parameters 28 | // The handler will emit an event with the combined object 29 | handler(topic, message); 30 | } 31 | }, 32 | 33 | resetMocks: () => { 34 | mockDpsnClient.init.mockClear(); 35 | mockDpsnClient.subscribe.mockClear(); 36 | mockDpsnClient.unsubscribe.mockClear(); 37 | mockDpsnClient.disconnect.mockClear(); 38 | mockDpsnClient.subscriptionHandlers = {}; 39 | }, 40 | }; 41 | 42 | export default mockDpsnClient; 43 | -------------------------------------------------------------------------------- /plugins/zytronPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game"; 2 | import ZytronPlugin from "./zytronPlugin"; 3 | import ZytronWallet from "./zytronWallet"; 4 | 5 | const zytronWallet = new ZytronWallet(""); 6 | 7 | const zytronPlugin = new ZytronPlugin({ 8 | id: "zytron_worker", 9 | name: "Zytron Worker", 10 | description: "This Worker enables users to execute interactions on the Zytron mainnet.", 11 | wallet: zytronWallet, 12 | }); 13 | 14 | const worker = zytronPlugin.getWorker([ 15 | zytronPlugin.checkWalletFunction, 16 | zytronPlugin.sendTokenFunction, 17 | ]); 18 | 19 | const agent = new GameAgent("", { 20 | name: "Zytron Bot", 21 | goal: "Interact with Zytron Mainnet", 22 | description: "A bot that can check balances and send tokens on Zytron Mainnet", 23 | workers: [ 24 | worker, 25 | ], 26 | }); 27 | 28 | (async () => { 29 | agent.setLogger((zytronAgent, message) => { 30 | console.log(`-----[${zytronAgent.name}]-----`); 31 | console.log(message); 32 | console.log("\n"); 33 | }); 34 | 35 | await agent.init(); 36 | const agentWorker = agent.getWorkerById(worker.id); 37 | 38 | const task = 'Check my wallet'; 39 | await agentWorker.runTask(task, { verbose: true }); 40 | 41 | // const task = 'Check 0x421E75Fe9Ad40baa99Ec1170957238A0Eba8d51C'; 42 | // await agentWorker.runTask(task, { verbose: true }); 43 | 44 | // const task = 'Send 0.0001 ETH to 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'; 45 | // await agentWorker.runTask(task, { verbose: true }); 46 | })(); 47 | -------------------------------------------------------------------------------- /plugins/acpPlugin/example/agentic/.env.example: -------------------------------------------------------------------------------- 1 | # ACP Agents' Credentials 2 | WHITELISTED_WALLET_PRIVATE_KEY=<0x-your-whitelisted-wallet-private-key> 3 | SELLER_ENTITY_ID= 4 | BUYER_ENTITY_ID= 5 | BUYER_AGENT_WALLET_ADDRESS=<0x-your-buyer-agent-wallet-address> 6 | SELLER_AGENT_WALLET_ADDRESS=<0x-your-seller-agent-wallet-address> 7 | 8 | # GAME API Key (get from https://console.game.virtuals.io/) 9 | GAME_API_KEY= 10 | 11 | # GAME Twitter Access Token for X (Twitter) Authentication 12 | BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN= 13 | SELLER_AGENT_GAME_TWITTER_ACCESS_TOKEN= 14 | 15 | # GAME Twitter Access Token for X (Twitter) Authentication 16 | BUYER_AGENT_TWITTER_BEARER_TOKEN= 17 | BUYER_AGENT_TWITTER_API_KEY= 18 | BUYER_AGENT_TWITTER_API_SECRET_KEY= 19 | BUYER_AGENT_TWITTER_ACCESS_TOKEN= 20 | BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET= 21 | SELLER_AGENT_TWITTER_BEARER_TOKEN= 22 | SELLER_AGENT_TWITTER_API_KEY= 23 | SELLER_AGENT_TWITTER_API_SECRET_KEY= 24 | SELLER_AGENT_TWITTER_ACCESS_TOKEN= 25 | SELLER_AGENT_TWITTER_ACCESS_TOKEN_SECRET= 26 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.fundamentalGrade.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create an agent to get fundamental grade insights for tokens 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Fundamental Grade Analyst", 15 | goal: "Get the latest Fundamental Grade insights for tokens, including grade class, community score, exchange score, VC score, tokenomics score, and DeFi scanner score.", 16 | description: 17 | "You are an AI agent specialized in analyzing cryptocurrency fundamental strength using TokenMetrics Fundamental Grade insights. You evaluate key fundamental factors including community engagement, exchange listings, venture capital backing, tokenomics design, and DeFi ecosystem integration to assess the long-term viability and potential of crypto projects.", 18 | workers: [ 19 | tokenMetricsPlugin.getWorker({ 20 | functions: [tokenMetricsPlugin.getFundamentalGrade], 21 | }), 22 | ], 23 | }); 24 | 25 | (async () => { 26 | agent.setLogger((agent, message) => { 27 | console.log(`-----[${agent.name}]-----`); 28 | console.log(message); 29 | console.log("\n"); 30 | }); 31 | 32 | await agent.init(); 33 | 34 | while (true) { 35 | await agent.step({ 36 | verbose: true, 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /plugins/acpPlugin/example/reactive/.env.example: -------------------------------------------------------------------------------- 1 | # ACP Agents' Credentials 2 | WHITELISTED_WALLET_PRIVATE_KEY=<0x-your-whitelisted-wallet-private-key> 3 | SELLER_ENTITY_ID= 4 | BUYER_ENTITY_ID= 5 | BUYER_AGENT_WALLET_ADDRESS=<0x-your-buyer-agent-wallet-address> 6 | SELLER_AGENT_WALLET_ADDRESS=<0x-your-seller-agent-wallet-address> 7 | 8 | # GAME API Key (get from https://console.game.virtuals.io/) 9 | GAME_API_KEY= 10 | 11 | # GAME Twitter Access Token for X (Twitter) Authentication 12 | BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN= 13 | SELLER_AGENT_GAME_TWITTER_ACCESS_TOKEN= 14 | 15 | # GAME Twitter Access Token for X (Twitter) Authentication 16 | BUYER_AGENT_TWITTER_BEARER_TOKEN= 17 | BUYER_AGENT_TWITTER_API_KEY= 18 | BUYER_AGENT_TWITTER_API_SECRET_KEY= 19 | BUYER_AGENT_TWITTER_ACCESS_TOKEN= 20 | BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET= 21 | SELLER_AGENT_TWITTER_BEARER_TOKEN= 22 | SELLER_AGENT_TWITTER_API_KEY= 23 | SELLER_AGENT_TWITTER_API_SECRET_KEY= 24 | SELLER_AGENT_TWITTER_ACCESS_TOKEN= 25 | SELLER_AGENT_TWITTER_ACCESS_TOKEN_SECRET= 26 | -------------------------------------------------------------------------------- /tools/cloud-to-sdk/generateAgent.ts: -------------------------------------------------------------------------------- 1 | // generateAgent.ts 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import { PluginJson } from './types'; 5 | import { GameAgent, LLMModel } from "@virtuals-protocol/game"; 6 | 7 | export function generateAgent(json: PluginJson, outputPath: string): void { 8 | try { 9 | // Ensure directory exists 10 | const dir = path.dirname(outputPath); 11 | if (!fs.existsSync(dir)) { 12 | fs.mkdirSync(dir, { recursive: true }); 13 | } 14 | 15 | const modelMapping: { [key: string]: string } = { 16 | 'llama_3_1_405b': 'Llama_3_1_405B_Instruct', 17 | 'llama_3_3_70b': 'Llama_3_3_70B_Instruct', 18 | 'deepseek_r1': 'DeepSeek_R1', 19 | 'deepseek_v3': 'DeepSeek_V3', 20 | 'qwen_2_5_72b': 'Qwen_2_5_72B_Instruct' 21 | }; 22 | 23 | const modelName = modelMapping[json.gameEngineModel.toLowerCase()] || 'Llama_3_3_70B_Instruct'; 24 | 25 | const content = ` 26 | import { GameAgent, LLMModel } from "@virtuals-protocol/game"; 27 | import { workers } from "./worker"; 28 | 29 | export const agent = new GameAgent("YOUR_API_KEY", { 30 | name: "${json.name || 'name'}", 31 | goal: \`${json.goal}\`, 32 | description: \`${json.description}\`, 33 | workers: workers, 34 | llmModel: LLMModel.${modelName} 35 | });`; 36 | 37 | fs.writeFileSync(outputPath, content); 38 | console.log(`✅ Generated agent.ts at ${outputPath}`); 39 | } catch (error) { 40 | console.error(`❌ Error generating agent.ts:`, error); 41 | throw error; 42 | } 43 | } -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ExecutableGameFunctionResponse, 3 | ExecutableGameFunctionStatus, 4 | } from "@virtuals-protocol/game"; 5 | 6 | export async function maopVisitor( 7 | apiKey: string, 8 | baseApiUrl: string, 9 | toolName: string, 10 | args: any, 11 | logger: any 12 | ) { 13 | // Prepare headers for the request 14 | const headers = { 15 | "content-type": "application/json", 16 | accept: "application/json", 17 | "x-game-plugin": "0.1", 18 | Authorization: apiKey, 19 | }; 20 | 21 | // Prepare request URL 22 | const url = new URL(`${baseApiUrl}/api/v3/game-plugin/run-tool`); 23 | 24 | logger(`Querying coin data with ID: ${args.id}`); 25 | 26 | // Make the API request 27 | const response = await fetch(url.href, { 28 | method: "post", 29 | headers, 30 | body: JSON.stringify({ toolName, args }), 31 | }); 32 | 33 | if (!response.ok) { 34 | throw new Error(`HTTP error! status: ${response.status}`); 35 | } 36 | 37 | const jsonResponse = await response.json(); 38 | // return jsonResponse; 39 | const message = `Successfully queried data. Response: ${JSON.stringify( 40 | jsonResponse 41 | )}`; 42 | logger(message); 43 | 44 | return new ExecutableGameFunctionResponse( 45 | ExecutableGameFunctionStatus.Done, 46 | message 47 | ); 48 | } 49 | 50 | export function exceptionHandler(e: any, logger: any) { 51 | const errorMessage = `An error occurred while querying coin data: ${ 52 | e.message || "Unknown error" 53 | }`; 54 | logger(errorMessage); 55 | 56 | return new ExecutableGameFunctionResponse( 57 | ExecutableGameFunctionStatus.Failed, 58 | errorMessage 59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /tools/cloud-to-sdk/README.md: -------------------------------------------------------------------------------- 1 | # Cloud-to-SDK Converter Tool 2 | 3 | This tool helps you convert GAME cloud configuration JSON files into SDK-compatible TypeScript files. 4 | 5 | ## Important Notes 6 | 7 | *Note: This tool provides a starting point for code generation but has some limitations:* 8 | 9 | * Always verify generated code before production use 10 | * Some edge cases might not automatically handled: 11 | * Complex function implementations 12 | * Special character handling in descriptions/hints 13 | * Some functions might have been abstracted by GAME Cloud and is not generated in the json file, in which case you will need to implement them manually 14 | * Manual review and modification may be needed 15 | 16 | ## Overview 17 | 18 | If you have an existing GAME configuration JSON file from the cloud platform, you can use this tool to automatically generate the necessary TypeScript files for SDK integration. 19 | 20 | ## Usage 21 | 22 | 1. Go to your GAME Cloud page, and click on the "Export Agent" button to download the JSON file 23 | 24 | Export JSON 25 | 26 | 2. Place your GAME cloud JSON file in the tools/cloud-to-sdk directory 27 | 3. Run the conversion tool with the following command: 28 | npm run cloud-to-sdk -- 29 | 30 | This will create an `output` directory containing: 31 | - agent.ts - Contains the GameAgent configuration 32 | - worker.ts - Contains worker definitions 33 | - functions.ts - Contains function implementations 34 | 35 | *note: the functions generated are currently incomplete, they just contain function name, description and a boilerplate implementation, you will need to implement them. 36 | 37 | -------------------------------------------------------------------------------- /plugins/tokenMetricsPlugin/src/examples/example.fullAgent.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: "./.env" }); 3 | import { GameAgent } from "@virtuals-protocol/game"; 4 | import TokenMetricsPlugin from "../index"; 5 | 6 | const tokenMetricsPlugin = new TokenMetricsPlugin({ 7 | apiClientConfig: { 8 | apiKey: process.env.TOKENMETRICS_API_KEY!, 9 | }, 10 | }); 11 | 12 | // Create a comprehensive crypto analysis agent with ALL TokenMetrics functions 13 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 14 | name: "TokenMetrics Comprehensive AI Crypto Analyst", 15 | goal: "Provide complete cryptocurrency analysis using all TokenMetrics AI capabilities including trader grades, investor grades, trading signals, market metrics, price data, technical analysis, AI reports, and investor intelligence.", 16 | description: 17 | "You are the most advanced AI cryptocurrency analyst powered by the complete TokenMetrics suite. You can perform short-term trading analysis, long-term investment evaluation, market condition assessment, technical analysis, quantitative modeling, AI research, and investor intelligence. You help users make informed decisions across all aspects of cryptocurrency trading and investment using comprehensive data-driven analysis from TokenMetrics' AI platform.", 18 | workers: [tokenMetricsPlugin.getWorker({})], // Include ALL 13 functions 19 | }); 20 | 21 | (async () => { 22 | agent.setLogger((agent, message) => { 23 | console.log(`-----[${agent.name}]-----`); 24 | console.log(message); 25 | console.log("\n"); 26 | }); 27 | 28 | await agent.init(); 29 | 30 | while (true) { 31 | await agent.step({ 32 | verbose: true, 33 | }); 34 | } 35 | })(); 36 | -------------------------------------------------------------------------------- /plugins/d.a.t.aPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | import { GameAgent } from "@virtuals-protocol/game"; 3 | import { createDataPlugin } from "./d.a.t.aPlugin"; 4 | 5 | // Load environment variables 6 | config(); 7 | 8 | // Example usage 9 | async function example() { 10 | try { 11 | // Create data plugin with environment variables 12 | const plugin = createDataPlugin(); 13 | const worker = plugin.getWorker(); 14 | 15 | // Create an agent with the worker 16 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 17 | name: "D.A.T.A Query Agent", 18 | goal: "Query and analyze Ethereum transaction data", 19 | description: "An agent that executes SQL queries against the CARV D.A.T.A API", 20 | workers: [worker], 21 | }); 22 | 23 | // Set up logging 24 | agent.setLogger((agent, message) => { 25 | console.log(`-----[${agent.name}]-----`); 26 | console.log(message); 27 | console.log("\n"); 28 | }); 29 | 30 | // Initialize agent 31 | await agent.init(); 32 | 33 | // Execute SQL query 34 | const sql = "SELECT * FROM eth.transactions LIMIT 2"; 35 | console.log(`\nExecuting query: ${sql}`); 36 | const result = await worker.functions[0].executable({ sql }, console.log); 37 | console.log("Query Result:", JSON.stringify(result, null, 2)); 38 | 39 | // Let the agent process the result 40 | await agent.step({ 41 | verbose: true, 42 | }); 43 | } catch (error) { 44 | console.error("Error in example:", error); 45 | } 46 | } 47 | 48 | // Run example 49 | example(); -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game"; 2 | import { getOnChainActionsWorker } from "."; 3 | import { base } from "viem/chains"; 4 | import { createWalletClient, http } from "viem"; 5 | import { PEPE, USDC, erc20 } from "@goat-sdk/plugin-erc20"; 6 | import { sendETH } from "@goat-sdk/wallet-evm"; 7 | import { viem } from "@goat-sdk/wallet-viem"; 8 | import { uniswap } from "@goat-sdk/plugin-uniswap"; 9 | import { privateKeyToAccount } from "viem/accounts"; 10 | 11 | const account = privateKeyToAccount( 12 | process.env.WALLET_PRIVATE_KEY as `0x${string}` 13 | ); 14 | 15 | const walletClient = createWalletClient({ 16 | account: account, 17 | transport: http(process.env.RPC_PROVIDER_URL), 18 | chain: base, 19 | }); 20 | 21 | (async () => { 22 | const onChainActionsWorker = await getOnChainActionsWorker({ 23 | wallet: viem(walletClient), 24 | plugins: [ 25 | sendETH(), 26 | erc20({ tokens: [USDC, PEPE] }), 27 | uniswap({ 28 | baseUrl: process.env.UNISWAP_BASE_URL as string, 29 | apiKey: process.env.UNISWAP_API_KEY as string, 30 | }), 31 | ], 32 | }); 33 | 34 | // Create an agent with the worker 35 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 36 | name: "On chain actions agent", 37 | goal: "Swap 0.01 USDC to PEPE", 38 | description: "An agent that executes onchain actions", 39 | workers: [onChainActionsWorker], 40 | }); 41 | 42 | agent.setLogger((agent, message) => { 43 | console.log(`-----[${agent.name}]-----`); 44 | console.log(message); 45 | console.log("\n"); 46 | }); 47 | 48 | await agent.init(); 49 | 50 | while (true) { 51 | await agent.step({ 52 | verbose: true, 53 | }); 54 | } 55 | })(); 56 | -------------------------------------------------------------------------------- /plugins/zytronPlugin/src/zytronWallet.ts: -------------------------------------------------------------------------------- 1 | import { Address, createPublicClient, createWalletClient, formatEther, Hex, http, parseUnits, PrivateKeyAccount, PublicClient, WalletClient } from "viem"; 2 | import { privateKeyToAccount } from "viem/accounts"; 3 | import { zytron } from "./constants"; 4 | 5 | interface ISendNativeTokenOptions { 6 | recipient: Address; 7 | value: bigint; 8 | } 9 | 10 | class ZytronWallet { 11 | private account: PrivateKeyAccount; 12 | private client: WalletClient; 13 | private publicClient: PublicClient; 14 | 15 | constructor(pk: string) { 16 | if (!pk) throw new Error('private key is missing'); 17 | const account = privateKeyToAccount((pk.startsWith("0x") ? pk : `0x${pk}`) as Hex); 18 | this.account = account; 19 | this.client = createWalletClient({ 20 | account, 21 | chain: zytron, 22 | transport: http(), 23 | }); 24 | this.publicClient = createPublicClient({ 25 | chain: zytron, 26 | transport: http(), 27 | }) 28 | } 29 | 30 | public async getBalance(address?: Address) { 31 | if (!address) { 32 | address = this.account.address; 33 | } 34 | const balance = await this.publicClient.getBalance({ address }); 35 | return { value: balance, format: formatEther(balance), symbol: zytron.nativeCurrency.symbol }; 36 | } 37 | 38 | public getAddress() { 39 | return this.account.address; 40 | } 41 | 42 | public async sendNativeToken(options: ISendNativeTokenOptions): Promise { 43 | const { recipient, value } = options; 44 | const hash = await this.client.sendTransaction({ 45 | value, 46 | account: this.account, 47 | to: recipient, 48 | chain: zytron, 49 | }); 50 | return hash; 51 | } 52 | } 53 | 54 | export default ZytronWallet; 55 | -------------------------------------------------------------------------------- /plugins/ensoPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game"; 2 | import { getEnsoWorker } from "."; 3 | import { base } from "viem/chains"; 4 | import { 5 | Address, 6 | createPublicClient, 7 | createWalletClient, 8 | http, 9 | PublicClient, 10 | } from "viem"; 11 | import { privateKeyToAccount } from "viem/accounts"; 12 | import * as dotenv from "dotenv"; 13 | 14 | dotenv.config(); 15 | 16 | const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as Address); 17 | 18 | const publicClient = createPublicClient({ 19 | transport: http(process.env.RPC_PROVIDER_URL), 20 | chain: base, 21 | }) as PublicClient; 22 | 23 | const walletClient = createWalletClient({ 24 | account: account, 25 | transport: http(process.env.RPC_PROVIDER_URL), 26 | chain: base, 27 | }); 28 | 29 | (async () => { 30 | const ensoActionsWorker = await getEnsoWorker({ 31 | wallet: walletClient, 32 | publicClient, 33 | apiKey: process.env.ENSO_API_KEY || "1e02632d-6feb-4a75-a157-documentation", 34 | }); 35 | 36 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 37 | name: "Enso Actions Agent", 38 | goal: "Find the best route between two tokens and execute it", 39 | description: 40 | "An agent that finds the best route between tokens and executes it", 41 | workers: [ensoActionsWorker], 42 | }); 43 | 44 | agent.setLogger((agent, message) => { 45 | console.log(`-----[${agent.name}]-----`); 46 | console.log(`${message}\n`); 47 | }); 48 | 49 | await agent.init(); 50 | const agentWorker = agent.getWorkerById(ensoActionsWorker.id); 51 | const task = `Swap 0.0002 WETH (address 0x4200000000000000000000000000000000000006) for USDC (address 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913)`; 52 | 53 | await agentWorker.runTask(task, { verbose: true }); 54 | })(); 55 | -------------------------------------------------------------------------------- /plugins/acpPlugin/src/interface.ts: -------------------------------------------------------------------------------- 1 | import { AcpJobPhases, IDeliverable } from "@virtuals-protocol/acp-node"; 2 | 3 | export enum AcpJobPhasesDesc { 4 | REQUEST = "request", 5 | NEGOTIATION = "pending_payment", 6 | TRANSACTION = "in_progress", 7 | EVALUATION = "evaluation", 8 | COMPLETED = "completed", 9 | REJECTED = "rejected", 10 | EXPIRED = "expired", 11 | } 12 | 13 | export const ACP_JOB_PHASE_MAP: Record = { 14 | [AcpJobPhases.REQUEST]: AcpJobPhasesDesc.REQUEST, 15 | [AcpJobPhases.NEGOTIATION]: AcpJobPhasesDesc.NEGOTIATION, 16 | [AcpJobPhases.TRANSACTION]: AcpJobPhasesDesc.TRANSACTION, 17 | [AcpJobPhases.EVALUATION]: AcpJobPhasesDesc.EVALUATION, 18 | [AcpJobPhases.COMPLETED]: AcpJobPhasesDesc.COMPLETED, 19 | [AcpJobPhases.REJECTED]: AcpJobPhasesDesc.REJECTED, 20 | [AcpJobPhases.EXPIRED]: AcpJobPhasesDesc.EXPIRED, 21 | }; 22 | 23 | export interface AcpRequestMemo { 24 | id: number; 25 | } 26 | 27 | export interface ITweet { 28 | type: "buyer" | "seller"; 29 | tweetId: string; 30 | content: string; 31 | createdAt: number; 32 | } 33 | 34 | export interface IAcpJob { 35 | jobId: number; 36 | clientName?: string; 37 | providerName?: string; 38 | desc: string; 39 | price: string; 40 | providerAddress?: string; 41 | phase: AcpJobPhasesDesc; 42 | memo: AcpRequestMemo[]; 43 | tweetHistory?: ITweet[]; 44 | } 45 | 46 | export interface IInventory extends IDeliverable { 47 | jobId: number; 48 | clientName?: string; 49 | providerName?: string; 50 | } 51 | 52 | export interface AcpState { 53 | inventory: { 54 | acquired: IInventory[]; 55 | produced: IInventory[]; 56 | }; 57 | jobs: { 58 | active: { 59 | asABuyer: IAcpJob[]; 60 | asASeller: IAcpJob[]; 61 | }; 62 | completed: IAcpJob[]; 63 | cancelled: IAcpJob[]; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /game-starter/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use a specific Node.js version for better reproducibility 2 | FROM node:23.3.0-slim AS builder 3 | 4 | # Install necessary build tools 5 | RUN apt-get update && \ 6 | apt-get upgrade -y && \ 7 | apt-get install -y \ 8 | git \ 9 | python3 \ 10 | python3-pip \ 11 | curl \ 12 | node-gyp \ 13 | ffmpeg \ 14 | libtool-bin \ 15 | autoconf \ 16 | automake \ 17 | libopus-dev \ 18 | make \ 19 | g++ \ 20 | build-essential \ 21 | libcairo2-dev \ 22 | libjpeg-dev \ 23 | libpango1.0-dev \ 24 | libgif-dev \ 25 | openssl \ 26 | libssl-dev libsecret-1-dev && \ 27 | apt-get clean && \ 28 | rm -rf /var/lib/apt/lists/* 29 | 30 | # Set Python 3 as the default python 31 | RUN ln -sf /usr/bin/python3 /usr/bin/python 32 | 33 | # Set the working directory 34 | WORKDIR /app 35 | 36 | # Copy application code 37 | COPY . . 38 | 39 | # Install dependencies 40 | RUN npm install --no-frozen-lockfile 41 | 42 | # Install TypeScript globally 43 | RUN npm install -g typescript 44 | 45 | # Build the project 46 | RUN npm run build && npm prune --production 47 | 48 | # Final runtime image 49 | FROM node:23.3.0-slim 50 | 51 | # Install runtime dependencies 52 | RUN apt-get update && \ 53 | apt-get install -y \ 54 | git \ 55 | python3 \ 56 | ffmpeg && \ 57 | apt-get clean && \ 58 | rm -rf /var/lib/apt/lists/* 59 | 60 | # Set the working directory 61 | WORKDIR /app 62 | 63 | # Copy built artifacts and production dependencies from the builder stage 64 | COPY --from=builder /app/package.json ./ 65 | COPY --from=builder /app/package-lock.json ./ 66 | COPY --from=builder /app/node_modules ./node_modules 67 | COPY --from=builder /app/dist ./dist 68 | 69 | # Expose necessary ports 70 | # EXPOSE 3000 71 | 72 | # Command to start the application 73 | CMD ["npm", "start"] 74 | -------------------------------------------------------------------------------- /plugins/alchemyPlugin/README.md: -------------------------------------------------------------------------------- 1 | # Alchemy Plugin for Virtuals Protocol 2 | 3 | The **Alchemy Plugin** provides a set of functions to retrieve on-chain data from the Alchemy API giving your agent the power to work with web3 data. With this plugin, you can fetch portfolio data—including transaction history, token details, NFT information, and NFT contracts—by querying wallet addresses across various supported networks. 4 | 5 | ## Features 6 | 7 | - **Transaction History:** Retrieve historical transactions for a given EVM wallet. 8 | - **Tokens by Wallet:** Get the tokens held by a wallet along with associated metadata and prices. 9 | - **Token Balances by Wallet:** Fetch current token balances for a wallet. 10 | - **NFTs by Wallet:** Retrieve NFTs currently owned by a wallet, with optional paging and metadata. 11 | - **NFT Contracts by Wallet:** Retrieve distinct NFT contracts (collections) owned by a wallet, including metadata. 12 | 13 | ## Installation 14 | 15 | The plugin comes in the `plugins` directory at the root of `game-node` official repo. You'll need your `ALCHEMY_API_KEY` to use it which you can get by [creating your free alchemy account](https://bit.ly/42Emg95). You'll also need your `VIRTUALS_API_TOKEN` which you can get from the [G.A.M.E console](https://console.game.virtuals.io/projects). Add these variables to your `.env` file. 16 | 17 | ## Usage 18 | 19 | An example of how to instantiate the plugin and create an agent is given in `src/example.ts` file. 20 | 21 | All you need to do is run these commands at the root of `alchemyPlugin`: 22 | 23 | - `npm install` 24 | - `npm run build` 25 | - `node dist/example.js` 26 | 27 | ## Development 28 | 29 | Feel free to modify or extend the plugin as needed. Contributions, bug reports, and feature requests are welcome! 30 | 31 | 1. Fork the repository. 32 | 2. Create a new branch with your feature or bug fix. 33 | 3. Submit a pull request with detailed descriptions of your changes. 34 | -------------------------------------------------------------------------------- /plugins/discordPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game"; 2 | import DiscordPlugin from "./discordPlugin"; 3 | 4 | // Create a worker with the functions 5 | const discordPlugin = new DiscordPlugin({ 6 | credentials: { 7 | botToken: "" 8 | }, 9 | }); 10 | 11 | const agent = new GameAgent("", { 12 | name: "Discord Bot", 13 | goal: "A bot that will auto reply messages", 14 | description: "This agent will auto reply to messages, add reactions, pin messages, and delete messages", 15 | workers: [ 16 | discordPlugin.getWorker({ 17 | // Define the functions that the worker can perform, by default it will use the all functions defined in the plugin 18 | functions: [ 19 | discordPlugin.sendMessageFunction, 20 | discordPlugin.addReactionFunction, 21 | discordPlugin.pinMessageFunction, 22 | discordPlugin.deleteMessageFunction, 23 | ], 24 | }), 25 | ], 26 | }); 27 | 28 | (async () => { 29 | agent.setLogger((agent, message) => { 30 | console.log(`-----[${agent.name}]-----`); 31 | console.log(message); 32 | console.log("\n"); 33 | }); 34 | 35 | await agent.init(); 36 | discordPlugin.onMessage(async (msg) => { 37 | if (msg.guild) { 38 | console.log(msg); 39 | console.log(`Guild Name: ${msg.guild.name}, Guild ID: ${msg.guild.id}`); 40 | } else { 41 | console.log('This message is not from a guild (e.g., DM).'); 42 | } 43 | if (msg.author.bot) { 44 | console.log('This message is from a bot.'); 45 | return; 46 | } 47 | const agentTgWorker = agent.getWorkerById(discordPlugin.getWorker().id); 48 | const task = "Reply to chat id: " + msg.channelId + " and the incoming is message: " + msg.content + " and the message id is: " + msg.id; 49 | 50 | await agentTgWorker.runTask(task, { 51 | verbose: true, // Optional: Set to true to log each step 52 | }); 53 | }); 54 | })(); 55 | 56 | -------------------------------------------------------------------------------- /plugins/coingeckoMaopPlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@virtuals-protocol/game-coingecko-maop-plugin", 3 | "version": "0.1.0", 4 | "description": "coingecko plugin for GAME SDK under questflow MAOP", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "tsup": "tsup src/index.ts --dts --format cjs,esm --out-dir dist", 11 | "example": "ts-node src/example.ts", 12 | "coinDataByID": "ts-node src/example.coinDataByID.ts", 13 | "coinPricesByAddress": "ts-node src/example.coinPricesByAddress.ts", 14 | "coinPricesByIDs": "ts-node src/example.coinPricesByIDs.ts", 15 | "coinsCategoriesList": "ts-node src/example.coinsCategoriesList.ts", 16 | "coinsListWithMarketData": "ts-node src/example.coinsListWithMarketData.ts", 17 | "newPoolsByNetwork": "ts-node src/example.newPoolsByNetwork.ts", 18 | "specificPoolData": "ts-node src/example.specificPoolData.ts", 19 | "tokenInfoByAddress": "ts-node src/example.tokenInfoByAddress.ts", 20 | "tokenPriceByAddresses": "ts-node src/example.tokenPriceByAddresses.ts", 21 | "topGainersLosersConfig": "ts-node src/example.topGainersLosersConfig.ts", 22 | "trendingPoolsByNetwork": "ts-node src/example.trendingPoolsByNetwork.ts", 23 | "trendingPoolsList": "ts-node src/example.trendingPoolsList.ts", 24 | "trendingSearchList": "ts-node src/example.trendingSearchList.ts" 25 | }, 26 | "author": "Questflow", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "@types/node": "^22.13.1", 30 | "dotenv": "^16.4.7", 31 | "ts-node-dev": "^2.0.0", 32 | "typescript": "^5.7.3" 33 | }, 34 | "dependencies": { 35 | "@virtuals-protocol/game": "^0.1.4", 36 | "tsup": "^8.3.5" 37 | }, 38 | "files": [ 39 | "dist" 40 | ], 41 | "repository": { 42 | "type": "git", 43 | "url": "https://github.com/game-by-virtuals/game-node" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import configPrettier from 'eslint-config-prettier' 3 | import importPlugin from 'eslint-plugin-import' 4 | import prettierPlugin from 'eslint-plugin-prettier' 5 | import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort' 6 | import tseslint from 'typescript-eslint' 7 | 8 | export default tseslint.config( 9 | { ignores: ['dist', 'node_modules', 'coverage'] }, 10 | { 11 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 12 | files: ['**/*.ts'], 13 | languageOptions: { 14 | ecmaVersion: 2020, 15 | }, 16 | plugins: { 17 | import: importPlugin, 18 | configPrettier: configPrettier, 19 | prettier: prettierPlugin, 20 | 'simple-import-sort': simpleImportSortPlugin, 21 | }, 22 | rules: { 23 | 'no-console': 1, 24 | 'prettier/prettier': [ 25 | 'error', 26 | { 27 | printWidth: 120, 28 | semi: false, 29 | singleQuote: true, 30 | tabWidth: 2, 31 | trailingComma: 'all', 32 | }, 33 | ], 34 | '@typescript-eslint/no-explicit-any': 'off', 35 | '@typescript-eslint/no-inferrable-types': 'off', 36 | '@typescript-eslint/array-type': ['error', { default: 'generic' }], 37 | '@typescript-eslint/typedef': [ 38 | 1, 39 | { 40 | arrayDestructuring: true, 41 | arrowParameter: true, 42 | memberVariableDeclaration: true, 43 | objectDestructuring: true, 44 | parameter: true, 45 | propertyDeclaration: true, 46 | variableDeclaration: true, 47 | variableDeclarationIgnoreFunction: true, 48 | }, 49 | ], 50 | 'simple-import-sort/imports': 'error', 51 | 'simple-import-sort/exports': 'error', 52 | 'import/first': 'error', 53 | 'import/newline-after-import': 'error', 54 | 'import/no-duplicates': 'error', 55 | }, 56 | }, 57 | ) 58 | -------------------------------------------------------------------------------- /plugins/farcasterPlugin/README.md: -------------------------------------------------------------------------------- 1 | # Farcaster Plugin for Virtuals Game 2 | 3 | This plugin allows you to integrate Farcaster functionalities into your Virtuals Game. With this plugin, you can post casts on the Farcaster network. 4 | 5 | ## Installation 6 | 7 | To install the plugin, use npm or yarn: 8 | 9 | ```bash 10 | npm install @virtuals-protocol/game-farcaster-plugin 11 | ``` 12 | 13 | or 14 | 15 | ```bash 16 | yarn add @virtuals-protocol/game-farcaster-plugin 17 | ``` 18 | 19 | ## Usage 20 | 21 | ### Importing the Plugin 22 | 23 | First, import the `FarcasterPlugin` class from the plugin: 24 | 25 | ```typescript 26 | import FarcasterPlugin from "@virtuals-protocol/game-farcaster-plugin"; 27 | ``` 28 | 29 | ### Creating a Worker 30 | 31 | Create a worker with the necessary Farcaster credentials: 32 | 33 | ```typescript 34 | const farcasterPlugin = new FarcasterPlugin({ 35 | credentials: { 36 | neynarApiKey: "your_neynar_api_key" 37 | }, 38 | }); 39 | ``` 40 | 41 | ### Creating an Agent 42 | 43 | Create an agent and add the worker to it: 44 | 45 | ```typescript 46 | import { GameAgent } from "@virtuals-protocol/game"; 47 | 48 | const agent = new GameAgent("API_KEY", { 49 | name: "Farcaster Bot", 50 | goal: "Engage with the Farcaster community", 51 | description: "A bot that can post casts on Farcaster", 52 | workers: [farcasterPlugin.getWorker()], 53 | }); 54 | ``` 55 | 56 | ### Running the Agent 57 | 58 | Initialize and run the agent: 59 | 60 | ```typescript 61 | (async () => { 62 | await agent.init(); 63 | 64 | while (true) { 65 | await agent.step({ 66 | verbose: true, 67 | }); 68 | } 69 | })(); 70 | ``` 71 | 72 | ## Available Functions 73 | 74 | The `FarcasterPlugin` currently provides the following function: 75 | 76 | - `postCastFunction`: Post a new cast to Farcaster. Takes two arguments: 77 | - `text`: The content of the cast 78 | - `cast_reasoning`: The reasoning behind the cast 79 | 80 | ## License 81 | 82 | This project is licensed under the MIT License. 83 | -------------------------------------------------------------------------------- /plugins/alloraPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { ChainSlug, PriceInferenceTimeframe, PriceInferenceToken } from "@alloralabs/allora-sdk"; 2 | import { GameAgent } from "@virtuals-protocol/game"; 3 | import AlloraPlugin from "."; 4 | 5 | 6 | const alloraPlugin = new AlloraPlugin({ 7 | apiClientConfig: { 8 | chainSlug: process.env.ALLORA_CHAIN_SLUG as ChainSlug, 9 | apiKey: process.env.ALLORA_API_KEY, // Default key: UP-17f415babba7482cb4b446a1 10 | }, 11 | }); 12 | 13 | // Create an agent with the worker 14 | const agent = new GameAgent(process.env.GAME_API_KEY ?? "", { 15 | name: "Allora Worker", 16 | goal: "Get the 5m price inference for BTC and Luna from Allora Network.", 17 | description: `You are an AI agent specialized in Allora Network. 18 | You are able to get price inferences from Allora Network and provide users insights into future price of different crypto assets. 19 | You are able to get details about the topics deployed on Allora Network and provide users insights into the topics. 20 | For all the active topics, you are able to get the latest inference using the topic id. 21 | The available assets for price inferences worker are ${Object.values(PriceInferenceToken).join(", ")}; 22 | for the following timeframes: ${Object.values(PriceInferenceTimeframe).join(", ")}. 23 | If a price inference is not available for a specific asset and timeframe, 24 | you should determine the topic id for the asset and timeframe and use the topics inferences worker to get the latest inference 25 | for the specified asset and timeframe. This will return the equivalent of a price inference for the asset and timeframe. 26 | `, 27 | workers: [ 28 | alloraPlugin.getWorker({}), 29 | ], 30 | }); 31 | 32 | (async () => { 33 | agent.setLogger((agent, message) => { 34 | console.log(`-----[${agent.name}]-----`); 35 | console.log(message); 36 | console.log("\n"); 37 | }); 38 | 39 | await agent.init(); 40 | 41 | while (true) { 42 | await agent.step({ 43 | verbose: true, 44 | }); 45 | } 46 | })(); 47 | -------------------------------------------------------------------------------- /src/interface/GameClient.ts: -------------------------------------------------------------------------------- 1 | import { Axios } from "axios"; 2 | import GameWorker from "../worker"; 3 | import { ExecutableGameFunctionResponseJSON } from "../function"; 4 | 5 | export interface Map { 6 | id: string; 7 | } 8 | 9 | export interface GameAgent { 10 | id: string; 11 | name: string; 12 | goal: string; 13 | description: string; 14 | } 15 | 16 | export enum ActionType { 17 | CallFunction = "call_function", 18 | ContinueFunction = "continue_function", 19 | Wait = "wait", 20 | TryToTalk = "try_to_talk", 21 | Conversation = "conversation", 22 | GoTo = "go_to", 23 | Unknown = "unknown", 24 | } 25 | 26 | export interface ActionArgs { 27 | location_id: string; 28 | task_id: string; 29 | fn_id: string; 30 | args: Record; 31 | fn_name: string; 32 | thought: string; 33 | } 34 | 35 | export interface GameAction { 36 | action_type: ActionType; 37 | action_args: ActionArgs; 38 | agent_state?: Record; 39 | } 40 | 41 | export enum LLMModel { 42 | Llama_3_1_405B_Instruct = "Llama-3.1-405B-Instruct", 43 | Llama_3_3_70B_Instruct = "Llama-3.3-70B-Instruct", 44 | DeepSeek_R1 = "DeepSeek-R1", 45 | DeepSeek_V3 = "DeepSeek-V3", 46 | Qwen_2_5_72B_Instruct = "Qwen-2.5-72B-Instruct", 47 | } 48 | 49 | export interface IGameClient { 50 | client: Axios | null; 51 | createMap(workers: GameWorker[]): Promise; 52 | createAgent( 53 | name: string, 54 | goal: string, 55 | description: string 56 | ): Promise; 57 | getAction( 58 | agentId: string, 59 | mapId: string, 60 | worker: GameWorker, 61 | gameActionResult: ExecutableGameFunctionResponseJSON | null, 62 | environment: Record, 63 | agentState: Record 64 | ): Promise; 65 | setTask(agentId: string, task: string): Promise; 66 | getTaskAction( 67 | agentId: string, 68 | submissionId: string, 69 | worker: GameWorker, 70 | gameActionResult: ExecutableGameFunctionResponseJSON | null, 71 | environment: Record 72 | ): Promise; 73 | } 74 | -------------------------------------------------------------------------------- /plugins/echochambersPlugin/README.md: -------------------------------------------------------------------------------- 1 | # Echochambers Plugin for GAME Protocol 2 | 3 | ## Overview 4 | This plugin enables GAME Protocol agents to interact with Echochambers, providing functionality for message sending, history retrieval, and metrics analysis. 5 | 6 | ## Features Added 7 | 8 | ### Core Functions 9 | 1. Message Sending 10 | - `sendMessageFunction`: Send messages to Echochambers rooms with reasoning context 11 | 12 | 2. History Retrieval 13 | - `getRoomHistoryFunction`: Get message history from specific rooms with customizable limits 14 | 15 | 3. Metrics Analysis 16 | - `getRoomMetricsFunction`: Get metrics for specific rooms 17 | - `getAgentMetricsFunction`: Get metrics for all agents in a room 18 | - `getMetricsHistoryFunction`: Get historical metrics data for rooms 19 | 20 | ### Infrastructure 21 | - New [EchochambersPlugin]() class for managing Echochambers interactions 22 | - REST API integration 23 | - Type-safe function definitions 24 | 25 | ## Implementation Details 26 | ### Core Components 27 | - [echochambersPlugin.ts]() Main plugin implementation with: 28 | - Message sending functionality 29 | - Room history retrieval 30 | - Room and agent metrics analysis 31 | - Metrics history tracking 32 | - `types.ts`: TypeScript interfaces for all Echochambers data structures 33 | - `example.ts`: Basic usage example 34 | - `example_mock.ts`: mock example 35 | 36 | ### Plugin Architecture 37 | - Follows GAME Protocol's worker/function pattern 38 | - Uses getter methods for function definitions (matching other plugins) 39 | - Implements proper TypeScript types for configuration and responses 40 | 41 | ## Testing 42 | - Verified all function implementations: 43 | - Message sending 44 | - History retrieval 45 | - Room metrics 46 | - Agent metrics 47 | - Metrics history 48 | - Validated TypeScript types and compilation 49 | 50 | ## Dependencies 51 | - No new dependencies beyond core GAME Protocol requirements 52 | - Uses standard `axios` for API calls 53 | 54 | ## Future Updates 55 | - WebSocket support 56 | - Advanced context tracking 57 | - Enhanced room management features 58 | -------------------------------------------------------------------------------- /plugins/twitterPlugin/example/index.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent, GameWorker } from "@virtuals-protocol/game"; 2 | import TwitterPlugin from "@virtuals-protocol/game-twitter-plugin"; 3 | import { TwitterApi } from "@virtuals-protocol/game-twitter-node"; 4 | 5 | const gameTwitterClient = new TwitterApi({ 6 | gameTwitterAccessToken: "xxxx", 7 | }); 8 | 9 | // const nativeTwitterClient = new TwitterApi({ 10 | // appKey: "xxxxxxx", 11 | // appSecret: "xxxxxxx", 12 | // accessToken: "xxxxxxx", 13 | // accessSecret: "xxxxxxxxx", 14 | // }); 15 | 16 | // Create a worker with the functions 17 | const twitterPlugin = new TwitterPlugin({ 18 | id: "twitter_worker", 19 | name: "Twitter Worker", 20 | description: 21 | "A worker that will execute tasks within the Twitter Social Platforms. It is capable of posting, reply, quote and like tweets.", 22 | twitterClient: gameTwitterClient, 23 | }); 24 | 25 | // Create an agent with the worker 26 | const agent = new GameAgent("xxxx", { 27 | name: "Twitter Bot", 28 | goal: "increase engagement and grow follower count", 29 | description: "A bot that can post tweets, reply to tweets, and like tweets", 30 | workers: [ 31 | // Use local GameWorker that's compatible with local GameAgent 32 | new GameWorker({ 33 | id: "twitter_worker", 34 | name: "Twitter Worker", 35 | description: "Twitter integration worker", 36 | functions: [ 37 | twitterPlugin.searchTweetsFunction, 38 | //twitterPlugin.replyTweetFunction, 39 | twitterPlugin.postTweetFunction, 40 | ], 41 | getEnvironment: async () => { 42 | return { 43 | ...(await twitterPlugin.getMetrics()), 44 | username: "virtualsprotocol", 45 | token_price: "$100.00", 46 | }; 47 | }, 48 | }), 49 | ], 50 | }); 51 | 52 | (async () => { 53 | agent.setLogger((agent, message) => { 54 | console.log(`-----[${agent.name}]-----`); 55 | console.log(message); 56 | console.log("\n"); 57 | }); 58 | 59 | await agent.init(); 60 | 61 | while (true) { 62 | await agent.step({ 63 | verbose: true, 64 | }); 65 | } 66 | })(); 67 | -------------------------------------------------------------------------------- /plugins/dpsnPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from '@virtuals-protocol/game'; 2 | import DpsnPlugin from './dpsnPlugin'; 3 | import dotenv from 'dotenv'; 4 | import path from 'path'; 5 | dotenv.config({ path: path.resolve(__dirname, '../.env') }); 6 | 7 | // Define the topic you want to subscribe to 8 | const TOPIC = 9 | '0xe14768a6d8798e4390ec4cb8a4c991202c2115a5cd7a6c0a7ababcaf93b4d2d4/BTCUSDT/ticker'; 10 | 11 | const dpsnPlugin = new DpsnPlugin({ 12 | credentials: { 13 | privateKey: process.env.EVM_WALLET_PRIVATE_KEY || '', 14 | dpsnUrl: process.env.DPSN_URL || '', 15 | chainOptions: { 16 | network: 'testnet', 17 | wallet_chain_type: 'ethereum', 18 | }, 19 | }, 20 | }); 21 | 22 | const agent = new GameAgent(process.env.VIRTUALS_API_KEY || '', { 23 | name: 'DPSN Bot', 24 | goal: 'A bot that consumes realtime data from dpsn', 25 | description: 'A bot that consumes realtime data from dpsn', 26 | workers: [ 27 | dpsnPlugin.getWorker({ 28 | functions: [ 29 | dpsnPlugin.subscribeToTopicFunction, 30 | dpsnPlugin.unsubscribeToTopicFunction, 31 | ], 32 | }), 33 | ], 34 | }); 35 | 36 | (async () => { 37 | agent.setLogger((agent, message) => { 38 | console.log(`---------[${agent.name}]--------`); 39 | console.log(message); 40 | console.log('\n'); 41 | }); 42 | 43 | await agent.init(); 44 | const agentDpsnWorker = agent.getWorkerById(agent.workers[0].id); 45 | 46 | dpsnPlugin.onMessage(({ topic, message }) => { 47 | console.log('Topic: ', topic); 48 | console.log('Message', message); 49 | }); 50 | 51 | try { 52 | await agentDpsnWorker.runTask(`subscribe to topic ${TOPIC}`, { 53 | verbose: true, 54 | }); 55 | await agentDpsnWorker.runTask(`unsubscribe to topic ${TOPIC}`, { 56 | verbose: true, 57 | }); 58 | await agentDpsnWorker.runTask(`disconnect`, { verbose: true }); 59 | 60 | // Keep the process running 61 | process.on('SIGINT', async () => { 62 | console.log('Disconnecting from DPSN...'); 63 | await dpsnPlugin.disconnect(); 64 | process.exit(0); 65 | }); 66 | } catch (error) { 67 | console.error('Error:', error); 68 | await dpsnPlugin.disconnect(); 69 | process.exit(1); 70 | } 71 | })(); 72 | -------------------------------------------------------------------------------- /examples/chat-agent-example/telegram-with-chatAgent-example.ts: -------------------------------------------------------------------------------- 1 | import TelegramPlugin from "../../plugins/telegramPlugin/src/telegramPlugin"; 2 | import { ChatAgent } from "../../src/chatAgent"; 3 | 4 | const telegramBot = new TelegramPlugin({ 5 | credentials: { 6 | botToken: process.env.TELEGRAM_BOT_TOKEN || "" 7 | } 8 | }) 9 | 10 | const chatAgent = new ChatAgent(process.env.GAME_API_KEY || "", "You are a helpful assistant") 11 | 12 | const main = async () => { 13 | // Track active chats using a Map 14 | const activeChats = new Map(); 15 | 16 | // Set up Telegram message handler 17 | telegramBot.onMessage(async (message) => { 18 | // Get or create chat for this user 19 | let chat = activeChats.get(message.from.id); 20 | if (!chat) { 21 | chat = await chatAgent.createChat({ 22 | partnerId: message.from.id.toString(), 23 | partnerName: message.from.first_name, 24 | actionSpace: [ 25 | telegramBot.sendMessageFunction, 26 | telegramBot.sendMediaFunction, 27 | telegramBot.createPollFunction, 28 | telegramBot.pinnedMessageFunction, 29 | telegramBot.unPinnedMessageFunction, 30 | telegramBot.deleteMessageFunction 31 | ], 32 | }); 33 | activeChats.set(message.from.id, chat); 34 | } 35 | 36 | const userMessage = message.text; 37 | const response = await chat.next(userMessage); 38 | 39 | if (response.functionCall) { 40 | console.log(`Function call: ${response.functionCall.fn_name}`); 41 | // The function will be automatically executed by the agent 42 | } 43 | 44 | if (response.message) { 45 | await telegramBot.sendMessageFunction.executable({ 46 | chat_id: message.chat.id, 47 | text: response.message 48 | }, console.log); 49 | } 50 | 51 | if (response.isFinished) { 52 | await telegramBot.sendMessageFunction.executable({ 53 | chat_id: message.chat.id, 54 | text: "Chat ended" 55 | }, console.log); 56 | } 57 | }); 58 | 59 | // Start the bot 60 | }; 61 | 62 | main().catch(console.error); -------------------------------------------------------------------------------- /examples/state-management/agent.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game" 2 | import dotenv from "dotenv"; 3 | dotenv.config({ path: __dirname + '/.env' }); 4 | 5 | import { HeadChef, IngredientManager } from "./worker" 6 | 7 | let moves = 3; 8 | const getAgentState = async () => { 9 | return { 10 | moves_left: moves 11 | } 12 | } 13 | 14 | export const setAgentState = (state: any) => { 15 | moves = state.moves_left; 16 | } 17 | 18 | export const updateMoves = (amount: number) => { 19 | moves = amount; 20 | } 21 | 22 | export const getMoves = () => { 23 | return moves; 24 | } 25 | 26 | if (!process.env.API_KEY) { 27 | throw new Error('API_KEY is required in environment variables'); 28 | } 29 | 30 | export const agent = new GameAgent(process.env.API_KEY, { 31 | name: "kitchen_manager", 32 | description: `You are a skilled restaurant manager overseeing a busy kitchen. Your main responsibilities are: 33 | 34 | 1. Working with the Ingredient Manager to: 35 | - Plan and maintain ingredient inventory 36 | - Stay within budget when ordering supplies 37 | - Ensure all necessary ingredients are available for upcoming dishes 38 | 39 | 2. Coordinating with the Head Chef to: 40 | - Prepare high-quality dishes using available ingredients 41 | - Maintain food quality standards 42 | - Maximize kitchen efficiency 43 | 44 | You have a limited number of actions you can take (shown as moves_left). Each time you delegate a task 45 | to either the Ingredient Manager or Head Chef, it uses one move. You must stop all operations when you 46 | have no moves remaining. 47 | 48 | Important: Never continue operations when moves_left reaches 0. If this happens, immediately stop and 49 | report the current status. 50 | NO MATTER WHAT, you must make sure that you STOP OPERATING when the moves_left <= 0. NO NEGATIVE MOVES_LEFT ALLOWED. 51 | If negative moves_left is detected, STOP PROCEEDING and STOP OPERATING.`, 52 | 53 | goal: "Run an efficient kitchen by coordinating ingredient purchases within budget and food preparation to produce the highest quality dishes possible with your available resources and time.", 54 | workers: [ 55 | IngredientManager, 56 | HeadChef 57 | ], 58 | getAgentState: getAgentState 59 | }) 60 | -------------------------------------------------------------------------------- /plugins/onChainActionsPlugin/src/onChainActionsPlugin.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ExecutableGameFunctionResponse, 3 | ExecutableGameFunctionStatus, 4 | GameFunction, 5 | GameWorker, 6 | } from "@virtuals-protocol/game"; 7 | 8 | import { 9 | PluginBase, 10 | ToolBase, 11 | WalletClientBase, 12 | getTools, 13 | } from "@goat-sdk/core"; 14 | 15 | import type { JSONSchemaType } from "ajv"; 16 | import { zodToJsonSchema } from "zod-to-json-schema"; 17 | 18 | export type GetToolsParams = { 19 | wallet: TWalletClient; 20 | plugins?: (PluginBase | PluginBase)[]; 21 | }; 22 | 23 | export async function getOnChainActionsWorker< 24 | TWalletClient extends WalletClientBase 25 | >(params: GetToolsParams) { 26 | const tools: ToolBase[] = await getTools({ 27 | wallet: params.wallet, 28 | plugins: params.plugins, 29 | }); 30 | 31 | const workerFunctions = tools.map((tool) => { 32 | // biome-ignore lint/suspicious/noExplicitAny: Fix types later 33 | const schema = zodToJsonSchema(tool.parameters as any, { 34 | target: "jsonSchema7", 35 | }) as JSONSchemaType; 36 | 37 | const properties = Object.keys(schema.properties); 38 | 39 | const args = properties.map((property) => ({ 40 | name: property, 41 | description: schema.properties[property].description ?? "", 42 | })); 43 | 44 | return new GameFunction({ 45 | name: tool.name, 46 | description: tool.description, 47 | args: args, 48 | executable: async (args: any) => { 49 | try { 50 | const result = await tool.execute(args); 51 | return new ExecutableGameFunctionResponse( 52 | ExecutableGameFunctionStatus.Done, 53 | JSON.stringify(result) 54 | ); 55 | } catch (e) { 56 | return new ExecutableGameFunctionResponse( 57 | ExecutableGameFunctionStatus.Failed, 58 | `Failed to execute tool: ${e}` 59 | ); 60 | } 61 | }, 62 | }); 63 | }); 64 | 65 | return new GameWorker({ 66 | id: "onchain_actions_worker", 67 | name: "Onchain Actions Worker", 68 | description: 69 | "Worker that executes onchain actions such as swaps, transfers, etc.", 70 | functions: [...workerFunctions], 71 | }); 72 | } 73 | -------------------------------------------------------------------------------- /plugins/echochambersPlugin/src/example.ts: -------------------------------------------------------------------------------- 1 | import { GameAgent } from "@virtuals-protocol/game"; 2 | import EchochambersPlugin from "./echochambersPlugin"; 3 | 4 | // Create plugin instance with credentials 5 | const echochambersPlugin = new EchochambersPlugin({ 6 | credentials: { 7 | apiKey: "your-api-key-here", // Replace with your API key 8 | }, 9 | sender: { 10 | username: "Virtuals_Agent", 11 | model: "VirtualsLLM" 12 | } 13 | }); 14 | 15 | // Create an agent with the worker 16 | const agent = new GameAgent("API_KEY", { 17 | name: "Echochambers Bot", 18 | goal: "monitor room metrics and engage in conversations", 19 | description: "A bot that can monitor room metrics, retrieve history, and send messages", 20 | workers: [ 21 | echochambersPlugin.getWorker({ 22 | // Define the functions that the worker can perform, by default it will use all functions defined in the plugin 23 | // functions: [ 24 | // echochambersPlugin.sendMessageFunction, 25 | // echochambersPlugin.getRoomHistoryFunction, 26 | // echochambersPlugin.getRoomMetricsFunction, 27 | // echochambersPlugin.getAgentMetricsFunction, 28 | // echochambersPlugin.getMetricsHistoryFunction, 29 | // ], 30 | // Define the environment variables that the worker can access 31 | // getEnvironment: async () => ({ 32 | // activeRoom: "general", 33 | // messagesSent: 0, 34 | // lastActivity: new Date().toISOString(), 35 | // metrics: { 36 | // totalMessagesSent: 0, 37 | // activeConversations: 0, 38 | // responseRate: 0, 39 | // averageResponseTime: 0 40 | // } 41 | // }), 42 | }), 43 | ], 44 | }); 45 | 46 | (async () => { 47 | // Set up logging 48 | agent.setLogger((agent, message) => { 49 | const timestamp = new Date().toISOString(); 50 | console.log(`\n-----[${timestamp}][${agent.name}]-----`); 51 | console.log(`Goal: ${agent.goal}`); 52 | console.log(`Message: ${message}\n`); 53 | }); 54 | 55 | // Initialize the agent 56 | await agent.init(); 57 | 58 | // Run the agent continuously 59 | while (true) { 60 | await agent.step({ 61 | verbose: true, 62 | }); 63 | 64 | // Optional: Add a delay between steps 65 | await new Promise(resolve => setTimeout(resolve, 60000)); // 1 minute delay 66 | } 67 | })(); 68 | -------------------------------------------------------------------------------- /plugins/mindNetworkPlugin/README.md: -------------------------------------------------------------------------------- 1 | # Mind Network Plugin for Virtuals GAME Framework 2 | 3 | A plugin for interacting with [Mind Network Hubs](https://dapp.mindnetwork.xyz/votetoearn/voteonhubs/) within the [Virtuals ecosystem](https://www.virtuals.io/). [CitizenZ](https://www.mindnetwork.xyz/citizenz) and broader communities can secure trust their agents operation and decisioning. 4 | 5 | ## Overview 6 | 7 | The [Mind Network](https://www.mindnetwork.xyz/) plugin empowers users to participate in secure, privacy-preserving voting on the Mind Network. Leveraging [Fully Homomorphic Encryption (FHE)](https://docs.mindnetwork.xyz/minddocs/developer-guide/fhe-validation), it ensures encrypted votes while allowing users to track rewards earned for their participation. Designed for seamless integration with the [Virtuals GAME Framework](https://whitepaper.virtuals.io/developer-documents/game-framework), this plugin enables interactive and guided actions for an enhanced user experience. 8 | 9 | ## Features 10 | - **Voter Registration:** Join the Mind Network's Randgen Hub and other hubs to participate in secure voting, validation and consensus. 11 | - **FHE Encryption:** Safeguard vote content using Fully Homomorphic Encryption. The key difference is encryption key is never shared but still be able to run computation over encrypted data. 12 | - **Submit Encrypted Votes:** Cast votes in Mind Network Hubs elections without compromising data privacy. So AI Agents can get consensus over collective predictions, inference and serving. 13 | - **Reward Tracking:** Monitor your vFHE rewards earned through voting contributions. 14 | 15 | ## Installation 16 | 17 | Depedency for the plugin: 18 | - [mind-randgen-sdk](https://github.com/mind-network/mind-sdk-randgen-ts) 19 | - [mind-sdk-hubs](https://github.com/mind-network/mind-sdk-hubs-ts) 20 | 21 | To install the plugin, use the following command: 22 | 23 | ```bash 24 | npm install @virtuals-protocol/game-mind-network-plugin 25 | ``` 26 | 27 | ## Configuration 28 | 29 | Before using the plugin, configure the necessary environment variables: 30 | 31 | ```bash 32 | MIND_HOT_WALLET_PRIVATE_KEY= 33 | MIND_COLD_WALLET_ADDRESS= 34 | ``` 35 | 36 | ## Support 37 | 38 | If you have any queries, please feel free to contact Mind Team via [Discord](https://discord.com/invite/UYj94MJdGJ) or [Twitter](https://x.com/mindnetwork_xyz). -------------------------------------------------------------------------------- /plugins/attpsPlugin/README.md: -------------------------------------------------------------------------------- 1 | # ATTPs Plugin for Virtuals Game 2 | 3 | The ATTPs Plugin enables G.A.M.E agents to interact with the ATTPs Platform, providing capabilities for agent creation, data verification, and price querying functionalities. 4 | 5 | ### Features 6 | - Create and register new agents on the ATTPs Platform 7 | - Verify data with agent signatures 8 | - Query price data from various feeds 9 | 10 | ### Available Functions 11 | 1. `createAndRegisterAgent`: Creates and registers a new agent with specified signers and settings 12 | 2. `verifyData`: Verifies data with provided signatures and metadata 13 | 3. `priceQuery`: Fetches price data for specific feeds and agents 14 | 15 | ## Installation 16 | 17 | To install the plugin, use npm or yarn: 18 | 19 | ```bash 20 | npm install @virtuals-protocol/game-attps-plugin 21 | ``` 22 | 23 | or 24 | 25 | ```bash 26 | yarn add @virtuals-protocol/game-attps-plugin 27 | ``` 28 | 29 | ## Usage 30 | 31 | ### Importing the Plugin 32 | 33 | First, import the `AttpsPlugin` class from the plugin: 34 | 35 | ```typescript 36 | import AttpsPlugin from "@virtuals-protocol/game-attps-plugin"; 37 | ``` 38 | 39 | ### Setup environment variables 40 | 41 | Set the following environment variables: 42 | - `RPC_URL`: The RPC URL for the blockchain network 43 | - `PRIVATE_KEY`: Your private key for transaction signing 44 | - `PROXY_ADDRESS`: The proxy address for the ATTPs Platform 45 | 46 | ### Creating a Worker 47 | 48 | Create a worker with the necessary credentials: 49 | 50 | ```typescript 51 | const attpsPlugin = new AttpsPlugin({ 52 | credentials: { 53 | proxyAddress: process.env.PROXY_ADDRESS, 54 | privateKey: process.env.PRIVATE_KEY, 55 | rpcUrl: process.env.RPC_URL, 56 | } 57 | }); 58 | ``` 59 | 60 | ### Creating an Agent 61 | 62 | Create an agent and add the worker to it: 63 | 64 | ```typescript 65 | import { GameAgent } from "@virtuals-protocol/game"; 66 | 67 | const agent = new GameAgent("GAME_API_KEY", { 68 | name: "ATTPs Bot", 69 | goal: "Create agents, verify data, and query price data.", 70 | description: "A bot that can interact with the ATTPs Platform", 71 | workers: [attpsPlugin.getWorker({})], 72 | }); 73 | ``` 74 | 75 | ### Running the Agent 76 | 77 | Initialize and run the agent: 78 | 79 | ```typescript 80 | (async () => { 81 | await agent.init(); 82 | 83 | while (true) { 84 | await agent.step({ 85 | verbose: true, 86 | }); 87 | } 88 | })(); 89 | ``` 90 | -------------------------------------------------------------------------------- /plugins/deskExchangePlugin/README.md: -------------------------------------------------------------------------------- 1 | # Desk Plugin 2 | 3 | A plugin for interacting with a trading desk/exchange, providing functionality for perpetual trading, account management, and order handling. 4 | 5 | ## Features 6 | 7 | - Account summary retrieval 8 | - Perpetual trading execution 9 | - Order management (placing and canceling orders) 10 | 11 | ## Installation 12 | 13 | ```bash 14 | pnpm install @virtuals-protocol/game-desk-exchange-plugin 15 | ``` 16 | 17 | ## Configuration 18 | 19 | The plugin requires the following environment variables: 20 | 21 | - `DESK_EXCHANGE_PRIVATE_KEY`: Your private key for authentication 22 | - `DESK_EXCHANGE_NETWORK`: Network to connect to (`mainnet` or `testnet`) 23 | 24 | ## Usage 25 | 26 | ### Initializing the Plugin 27 | 28 | ```typescript 29 | import DeskExchangePlugin from '@virtuals-protocol/game-desk-exchange-plugin' 30 | 31 | const deskExchangePlugin = new DeskExchangePlugin({ 32 | credentials: { 33 | network: 'testnet', // or 'mainnet' 34 | privateKey: 'YOUR_PRIVATE_KEY' 35 | } 36 | }) 37 | ``` 38 | 39 | ### Available Functions 40 | 41 | #### Get Account Summary 42 | 43 | Retrieves a comprehensive summary of your account, including positions, orders, and collaterals. 44 | 45 | ```typescript 46 | const summary = await deskExchangePlugin.getAccountSummary.executable({}, logger) 47 | ``` 48 | 49 | #### Place Perpetual Trade 50 | 51 | Execute a perpetual trade with specified parameters. 52 | 53 | ```typescript 54 | const tradeRequest = { 55 | amount: '1', // Desired amount 56 | price: '10000', // Market price 57 | side: 'Long', // 'Long' or 'Short' 58 | symbol: 'BTC' // Trading pair symbol (without 'USD') 59 | } 60 | 61 | const trade = await deskExchangePlugin.perpTrade.executable(tradeRequest, logger) 62 | ``` 63 | 64 | #### Cancel Orders 65 | 66 | Cancel all open orders for the account. 67 | 68 | ```typescript 69 | const cancelResult = await deskExchangePlugin.cancelOrders.executable({}, logger) 70 | ``` 71 | 72 | ## Response Format 73 | 74 | All functions return an `ExecutableGameFunctionResponse` with the following structure: 75 | 76 | ```typescript 77 | { 78 | status: ExecutableGameFunctionStatus; 79 | feedback: string; 80 | } 81 | ``` 82 | 83 | ## Testing 84 | 85 | To run the tests: 86 | 87 | ```bash 88 | pnpm test 89 | ``` 90 | 91 | Make sure to set up the required environment variables before running tests. 92 | 93 | ## License 94 | 95 | [License Type] - See LICENSE file for details -------------------------------------------------------------------------------- /plugins/acpPlugin/example/agentic/env.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import { Address } from "viem"; 3 | 4 | dotenv.config({ path: __dirname + '/.env' }); 5 | 6 | function getEnvVar(key: string, required = true): T { 7 | const value = process.env[key]; 8 | if (required && (value === undefined || value === '')) { 9 | throw new Error(`${key} is not defined or is empty in the .env file`); 10 | } 11 | return value as T; 12 | } 13 | 14 | // ACP Agents' Credentials 15 | export const WHITELISTED_WALLET_PRIVATE_KEY = getEnvVar
('WHITELISTED_WALLET_PRIVATE_KEY'); 16 | export const SELLER_ENTITY_ID = parseInt(getEnvVar('SELLER_ENTITY_ID'), 10); 17 | export const BUYER_ENTITY_ID = parseInt(getEnvVar('BUYER_ENTITY_ID'), 10); 18 | export const BUYER_AGENT_WALLET_ADDRESS = getEnvVar('BUYER_AGENT_WALLET_ADDRESS') as Address; 19 | export const SELLER_AGENT_WALLET_ADDRESS = getEnvVar
('SELLER_AGENT_WALLET_ADDRESS') as Address; 20 | 21 | // GAME Dev API Key 22 | export const GAME_API_KEY = getEnvVar('GAME_API_KEY'); 23 | 24 | // GAME Twitter Access Token for X (Twitter) Authentication 25 | export const BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN = getEnvVar('BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN'); 26 | export const SELLER_AGENT_GAME_TWITTER_ACCESS_TOKEN = getEnvVar('SELLER_AGENT_GAME_TWITTER_ACCESS_TOKEN'); 27 | 28 | // Twitter API Credentials for X (Twitter) Authentication 29 | // export const BUYER_AGENT_TWITTER_API_KEY = getEnvVar('BUYER_AGENT_TWITTER_API_KEY'); 30 | // export const BUYER_AGENT_TWITTER_API_SECRET_KEY = getEnvVar('BUYER_AGENT_TWITTER_API_SECRET_KEY'); 31 | // export const BUYER_AGENT_TWITTER_ACCESS_TOKEN = getEnvVar('BUYER_AGENT_TWITTER_ACCESS_TOKEN'); 32 | // export const BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET = getEnvVar('BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET'); 33 | // export const SELLER_AGENT_TWITTER_API_KEY = getEnvVar('SELLER_AGENT_TWITTER_API_KEY'); 34 | // export const SELLER_AGENT_TWITTER_API_SECRET_KEY = getEnvVar('SELLER_AGENT_TWITTER_API_SECRET_KEY'); 35 | // export const SELLER_AGENT_TWITTER_ACCESS_TOKEN = getEnvVar('SELLER_AGENT_TWITTER_ACCESS_TOKEN'); 36 | // export const SELLER_AGENT_TWITTER_ACCESS_TOKEN_SECRET = getEnvVar('SELLER_AGENT_TWITTER_ACCESS_TOKEN_SECRET'); 37 | 38 | if (isNaN(BUYER_ENTITY_ID)) { 39 | throw new Error('BUYER_ENTITY_ID must be a valid number in the .env file'); 40 | } 41 | 42 | if (isNaN(SELLER_ENTITY_ID)) { 43 | throw new Error('SELLER_ENTITY_ID must be a valid number in the .env file'); 44 | } -------------------------------------------------------------------------------- /plugins/acpPlugin/example/reactive/env.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import { Address } from "viem"; 3 | 4 | dotenv.config({ path: __dirname + '/.env' }); 5 | 6 | function getEnvVar(key: string, required = true): T { 7 | const value = process.env[key]; 8 | if (required && (value === undefined || value === '')) { 9 | throw new Error(`${key} is not defined or is empty in the .env file`); 10 | } 11 | return value as T; 12 | } 13 | 14 | // ACP Agents' Credentials 15 | export const WHITELISTED_WALLET_PRIVATE_KEY = getEnvVar
('WHITELISTED_WALLET_PRIVATE_KEY'); 16 | export const SELLER_ENTITY_ID = parseInt(getEnvVar('SELLER_ENTITY_ID'), 10); 17 | export const BUYER_ENTITY_ID = parseInt(getEnvVar('BUYER_ENTITY_ID'), 10); 18 | export const BUYER_AGENT_WALLET_ADDRESS = getEnvVar('BUYER_AGENT_WALLET_ADDRESS') as Address; 19 | export const SELLER_AGENT_WALLET_ADDRESS = getEnvVar
('SELLER_AGENT_WALLET_ADDRESS') as Address; 20 | 21 | // GAME Dev API Key 22 | export const GAME_API_KEY = getEnvVar('GAME_API_KEY'); 23 | 24 | // GAME Twitter Access Token for X (Twitter) Authentication 25 | export const BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN = getEnvVar('BUYER_AGENT_GAME_TWITTER_ACCESS_TOKEN'); 26 | export const SELLER_AGENT_GAME_TWITTER_ACCESS_TOKEN = getEnvVar('SELLER_AGENT_GAME_TWITTER_ACCESS_TOKEN'); 27 | 28 | // Twitter API Credentials for X (Twitter) Authentication 29 | // export const BUYER_AGENT_TWITTER_API_KEY = getEnvVar('BUYER_AGENT_TWITTER_API_KEY'); 30 | // export const BUYER_AGENT_TWITTER_API_SECRET_KEY = getEnvVar('BUYER_AGENT_TWITTER_API_SECRET_KEY'); 31 | // export const BUYER_AGENT_TWITTER_ACCESS_TOKEN = getEnvVar('BUYER_AGENT_TWITTER_ACCESS_TOKEN'); 32 | // export const BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET = getEnvVar('BUYER_AGENT_TWITTER_ACCESS_TOKEN_SECRET'); 33 | // export const SELLER_AGENT_TWITTER_API_KEY = getEnvVar('SELLER_AGENT_TWITTER_API_KEY'); 34 | // export const SELLER_AGENT_TWITTER_API_SECRET_KEY = getEnvVar('SELLER_AGENT_TWITTER_API_SECRET_KEY'); 35 | // export const SELLER_AGENT_TWITTER_ACCESS_TOKEN = getEnvVar('SELLER_AGENT_TWITTER_ACCESS_TOKEN'); 36 | // export const SELLER_AGENT_TWITTER_ACCESS_TOKEN_SECRET = getEnvVar('SELLER_AGENT_TWITTER_ACCESS_TOKEN_SECRET'); 37 | 38 | if (isNaN(BUYER_ENTITY_ID)) { 39 | throw new Error('BUYER_ENTITY_ID must be a valid number in the .env file'); 40 | } 41 | 42 | if (isNaN(SELLER_ENTITY_ID)) { 43 | throw new Error('SELLER_ENTITY_ID must be a valid number in the .env file'); 44 | } --------------------------------------------------------------------------------