├── .env.example ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ └── build.yml ├── .gitignore ├── .husky └── pre-commit ├── .lintstagedrc ├── .prettierignore ├── .prettierrc ├── CITATION.cff ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── docs ├── .nojekyll ├── assets │ ├── hierarchy.js │ ├── highlight.css │ ├── icons.js │ ├── icons.svg │ ├── main.js │ ├── navigation.js │ ├── search.js │ └── style.css ├── classes │ └── SolanaAgentKit.html ├── functions │ ├── createSolanaTools.html │ ├── createVercelAITools.html │ ├── executeAction.html │ ├── findAction.html │ └── getActionExamples.html ├── index.html ├── interfaces │ ├── Action.html │ ├── ActionExample.html │ ├── BatchOrderPattern.html │ ├── CollectionDeployment.html │ ├── CollectionOptions.html │ ├── Config.html │ ├── Creator.html │ ├── FetchPriceResponse.html │ ├── FlashCloseTradeParams.html │ ├── FlashTradeParams.html │ ├── GibworkCreateTaskReponse.html │ ├── HeliusWebhookIdResponse.html │ ├── HeliusWebhookResponse.html │ ├── JupiterTokenData.html │ ├── LuloAccountDetailsResponse.html │ ├── MintCollectionNFTResponse.html │ ├── OrderParams.html │ ├── PriorityFeeResponse.html │ ├── PumpFunTokenOptions.html │ ├── PumpfunLaunchResponse.html │ ├── PythFetchPriceResponse.html │ ├── PythPriceFeedIDItem.html │ ├── PythPriceItem.html │ └── TokenCheck.html ├── media │ └── CONTRIBUTING.md ├── modules.html ├── types │ └── Handler.html └── variables │ └── actions.html ├── examples ├── agent-kit-langgraph │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── assets │ │ └── architecture.png │ ├── langgraph.json │ ├── package.json │ ├── pnpm-lock.yaml │ ├── src │ │ ├── agents │ │ │ ├── generalAgent.ts │ │ │ ├── manager.ts │ │ │ ├── readAgent.ts │ │ │ └── transferOrSwap.ts │ │ ├── helper │ │ │ ├── examples.ts │ │ │ └── tokenList.ts │ │ ├── index.ts │ │ ├── prompts │ │ │ ├── manager.ts │ │ │ └── transferSwap.ts │ │ ├── tools │ │ │ └── swap.ts │ │ └── utils │ │ │ ├── model.ts │ │ │ ├── route.ts │ │ │ ├── solanaAgent.ts │ │ │ └── state.ts │ └── tsconfig.json ├── agent-kit-nextjs-langchain │ ├── .env.example │ ├── .eslintrc.json │ ├── .gitignore │ ├── .prettierrc.json │ ├── LICENSE │ ├── README.md │ ├── app │ │ ├── api │ │ │ └── chat │ │ │ │ └── route.ts │ │ ├── globals.css │ │ ├── layout.tsx │ │ └── page.tsx │ ├── components │ │ ├── ChatMessageBubble.tsx │ │ ├── ChatWindow.tsx │ │ └── IntermediateStep.tsx │ ├── data │ │ └── DefaultRetrievalText.ts │ ├── next.config.js │ ├── package.json │ ├── pnpm-lock.yaml │ ├── postcss.config.js │ ├── public │ │ └── images │ │ │ ├── favicon.ico │ │ │ ├── og-image.png │ │ │ └── title-card.png │ ├── tailwind.config.js │ ├── tsconfig.json │ └── utils │ │ └── markdownToHTML.ts ├── discord-bot-starter │ ├── .env.template │ ├── .eslintrc.ts │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── pnpm-lock.yaml │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── market-making-agent │ ├── .env.example │ ├── README.md │ ├── index.ts │ ├── package.json │ └── pnpm-lock.yaml ├── persistent-agent │ ├── .env.example │ ├── README.md │ ├── index.ts │ ├── package.json │ └── pnpm-lock.yaml └── tg-bot-starter │ ├── README.md │ ├── advanced-tg-bot │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── next.config.ts │ ├── package.json │ ├── pnpm-lock.yaml │ ├── postcss.config.mjs │ ├── public │ │ ├── file.svg │ │ ├── globe.svg │ │ ├── next.svg │ │ ├── vercel.svg │ │ └── window.svg │ ├── src │ │ └── app │ │ │ ├── api │ │ │ └── bot │ │ │ │ └── route.ts │ │ │ ├── favicon.ico │ │ │ ├── globals.css │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ ├── tailwind.config.ts │ └── tsconfig.json │ ├── basic-tg-bot │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── next.config.ts │ ├── package.json │ ├── pnpm-lock.yaml │ ├── postcss.config.mjs │ ├── public │ │ ├── file.svg │ │ ├── globe.svg │ │ ├── next.svg │ │ ├── vercel.svg │ │ └── window.svg │ ├── src │ │ └── app │ │ │ ├── api │ │ │ └── bot │ │ │ │ └── route.ts │ │ │ ├── favicon.ico │ │ │ ├── globals.css │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ ├── tailwind.config.ts │ └── tsconfig.json │ └── group-tg-bot │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── next.config.ts │ ├── package.json │ ├── pnpm-lock.yaml │ ├── postcss.config.mjs │ ├── public │ ├── file.svg │ ├── globe.svg │ ├── next.svg │ ├── vercel.svg │ └── window.svg │ ├── src │ └── app │ │ ├── api │ │ └── bot │ │ │ └── route.ts │ │ ├── favicon.ico │ │ ├── globals.css │ │ ├── layout.tsx │ │ └── page.tsx │ ├── tailwind.config.ts │ └── tsconfig.json ├── guides ├── add_your_own_tool.md ├── setup_locally.md └── test_it_out.md ├── package.json ├── pnpm-lock.yaml ├── src ├── actions │ ├── agent │ │ ├── createImage.ts │ │ ├── getWalletAddress.ts │ │ └── get_info.ts │ ├── alldomains │ │ ├── getAllDomainsTLDs.ts │ │ ├── getOwnedAllDomains.ts │ │ ├── getOwnedDomainsForTLD.ts │ │ └── resolveDomain.ts │ ├── allora │ │ ├── getAllTopics.ts │ │ ├── getInferenceByTopicId.ts │ │ └── getPriceInference.ts │ ├── dexscreener │ │ └── tokenDataByTicker.ts │ ├── drift │ │ ├── availableMarkets.ts │ │ ├── createDriftUserAccount.ts │ │ ├── createVault.ts │ │ ├── depositIntoVault.ts │ │ ├── depositToDriftUserAccount.ts │ │ ├── deriveVaultAddress.ts │ │ ├── doesUserHaveDriftAccount.ts │ │ ├── driftUserAccountInfo.ts │ │ ├── entryQuoteOfPerpTrade.ts │ │ ├── getLendAndBorrowAPY.ts │ │ ├── perpMarketFundingRate.ts │ │ ├── requestUnstakeFromDriftInsuranceFund.ts │ │ ├── requestWithdrawalFromVault.ts │ │ ├── stakeToDriftInsuranceFund.ts │ │ ├── swapSpotToken.ts │ │ ├── tradeDelegatedDriftVault.ts │ │ ├── tradePerpAccount.ts │ │ ├── unstakeFromDriftInsuranceFund.ts │ │ ├── updateDriftVaultDelegate.ts │ │ ├── updateVault.ts │ │ ├── vaultInfo.ts │ │ ├── withdrawFromDriftAccount.ts │ │ └── withdrawFromVault.ts │ ├── flash │ │ ├── flashCloseTrade.ts │ │ └── flashOpenTrade.ts │ ├── gibwork │ │ └── createGibworkTask.ts │ ├── helius │ │ ├── createWebhook.ts │ │ ├── deleteWebhook.ts │ │ ├── getAssetsbyOwner.ts │ │ ├── getWebhook.ts │ │ ├── parseTransaction.ts │ │ └── sendTransactionWithPriority.ts │ ├── index.ts │ ├── jupiter │ │ ├── fetchPrice.ts │ │ ├── getTokenData.ts │ │ ├── stakeWithJup.ts │ │ └── trade.ts │ ├── lightprotocol │ │ └── compressedAirdrop.ts │ ├── lulo │ │ ├── lendAsset.ts │ │ ├── luloLend.ts │ │ └── luloWithdraw.ts │ ├── metaplex │ │ ├── deployCollection.ts │ │ ├── deployToken.ts │ │ ├── getAsset.ts │ │ ├── getAssetsByAuthority.ts │ │ ├── getAssetsByCreator.ts │ │ └── mintNFT.ts │ ├── openbook │ │ └── createOpenbookMarket.ts │ ├── orca │ │ └── createOrcaSingleSidedWhirlpool.ts │ ├── pumpfun │ │ └── launchPumpfunToken.ts │ ├── pyth │ │ └── pythFetchPrice.ts │ ├── raydium │ │ ├── raydiumCreateAmmV4.ts │ │ ├── raydiumCreateClmm.ts │ │ └── raydiumCreateCpmm.ts │ ├── sns │ │ ├── getAllRegisteredAllDomains.ts │ │ ├── getMainAllDomainsDomain.ts │ │ ├── getPrimaryDomain.ts │ │ ├── registerDomain.ts │ │ └── resolveSolDomain.ts │ ├── solana │ │ ├── balance.ts │ │ ├── closeEmptyTokenAccounts.ts │ │ ├── getTPS.ts │ │ ├── requestFunds.ts │ │ └── transfer.ts │ ├── solayer │ │ └── stakeWithSolayer.ts │ ├── squads │ │ ├── approveMultisigProposal.ts │ │ ├── createMultisig.ts │ │ ├── createMultisigProposal.ts │ │ ├── depositToMultisigTreasury.ts │ │ ├── executeMultisigProposal.ts │ │ ├── rejectMultisigProposal.ts │ │ └── transferFromMultisigTreasury.ts │ ├── tokenBalances.ts │ └── voltr │ │ ├── depositStrategy.ts │ │ ├── getPositionValues.ts │ │ └── withdrawStrategy.ts ├── agent │ └── index.ts ├── constants │ └── index.ts ├── idls │ └── adrena.ts ├── index.ts ├── langchain │ ├── 3land │ │ ├── create_collection.ts │ │ ├── create_single.ts │ │ └── index.ts │ ├── adrena │ │ ├── close_trade.ts │ │ ├── index.ts │ │ └── open_trade.ts │ ├── agent │ │ ├── create_image.ts │ │ ├── get_info.ts │ │ ├── index.ts │ │ └── wallet_address.ts │ ├── alldomains │ │ ├── get_all_tld.ts │ │ ├── index.ts │ │ ├── owned_domains.ts │ │ ├── resolve_all_domains.ts │ │ └── tld_domains.ts │ ├── allora │ │ ├── get_all_topics.ts │ │ ├── get_inference_by_topic_id.ts │ │ ├── get_price_inference.ts │ │ └── index.ts │ ├── dexscreener │ │ ├── index.ts │ │ └── token_data_ticker.ts │ ├── drift │ │ ├── create_user_account.ts │ │ ├── create_vault.ts │ │ ├── deposit_into_vault.ts │ │ ├── deposit_to_user_account.ts │ │ ├── derive_vault_address.ts │ │ ├── does_user_have_drift_account.ts │ │ ├── drift_user_account_info.ts │ │ ├── entry_quote_of_perp_trade.ts │ │ ├── index.ts │ │ ├── lend_and_borrow_apy.ts │ │ ├── perp_market_funding_rate.ts │ │ ├── request_unstake_from_insurance_fund.ts │ │ ├── request_withdrawal.ts │ │ ├── stake_to_insurance_fund.ts │ │ ├── swap_spot_token.ts │ │ ├── trade_delegated_vault.ts │ │ ├── trade_perp_account.ts │ │ ├── unstake_from_insurance_fund.ts │ │ ├── update_drift_vault_delegate.ts │ │ ├── update_vault.ts │ │ ├── vault_info.ts │ │ ├── withdraw_from_account.ts │ │ └── withdraw_from_vault.ts │ ├── flash │ │ ├── flash_close.ts │ │ ├── flash_open.ts │ │ └── index.ts │ ├── gibwork │ │ ├── create_task.ts │ │ └── index.ts │ ├── helius │ │ ├── create_webhook.ts │ │ ├── delete_webhook.ts │ │ ├── get_all_assets.ts │ │ ├── get_webhook.ts │ │ ├── index.ts │ │ ├── parse_transaction.ts │ │ └── send_transaction_priority.ts │ ├── index.ts │ ├── jupiter │ │ ├── fetch_price.ts │ │ ├── index.ts │ │ ├── stake.ts │ │ ├── token_data.ts │ │ └── trade.ts │ ├── lightprotocol │ │ ├── compressed_airdrop.ts │ │ └── index.ts │ ├── lulo │ │ ├── index.ts │ │ ├── lend_asset.ts │ │ ├── lulo_lend.ts │ │ └── lulo_withdraw.ts │ ├── manifest │ │ ├── batch_order.ts │ │ ├── cancel_orders.ts │ │ ├── index.ts │ │ ├── limit_order.ts │ │ ├── manifest_market.ts │ │ └── withdraw.ts │ ├── metaplex │ │ ├── deploy_collection.ts │ │ ├── deploy_token.ts │ │ ├── get_asset.ts │ │ ├── get_assets_by_authority.ts │ │ ├── get_assets_by_creator.ts │ │ ├── index.ts │ │ └── mint_nft.ts │ ├── meteora │ │ ├── index.ts │ │ ├── meteora_dlmm_pool.ts │ │ └── meteora_dynamic_pool.ts │ ├── openbook │ │ ├── index.ts │ │ └── openbook_market.ts │ ├── orca │ │ ├── index.ts │ │ ├── orca_centered_position.ts │ │ ├── orca_clmm.ts │ │ ├── orca_fetch_positions.ts │ │ ├── orca_position.ts │ │ ├── orca_single_sided_pool.ts │ │ └── orca_single_sided_position.ts │ ├── pumpfun │ │ ├── index.ts │ │ └── launch_pumpfun_token.ts │ ├── pyth │ │ ├── index.ts │ │ └── pyth_price.ts │ ├── raydium │ │ ├── index.ts │ │ ├── raydium_amm.ts │ │ ├── raydium_clmm.ts │ │ ├── raydium_cpmm.ts │ │ └── types.ts │ ├── rugcheck │ │ ├── index.ts │ │ ├── token_report_detailed.ts │ │ └── token_report_summary.ts │ ├── sendarcade │ │ ├── index.ts │ │ └── rock_paper_scissors.ts │ ├── sns │ │ ├── get_domain.ts │ │ ├── index.ts │ │ ├── main_domain.ts │ │ ├── register_domain.ts │ │ └── resolve_domain.ts │ ├── solana │ │ ├── balance.ts │ │ ├── balance_other.ts │ │ ├── close_empty_accounts.ts │ │ ├── get_tps.ts │ │ ├── index.ts │ │ ├── request_funds.ts │ │ └── transfer.ts │ ├── solayer │ │ ├── index.ts │ │ └── restake.ts │ ├── squads │ │ ├── approve_proposal.ts │ │ ├── create_multisig.ts │ │ ├── create_proposal.ts │ │ ├── deposit_to_multisig.ts │ │ ├── execute_proposal.ts │ │ ├── index.ts │ │ ├── reject_proposal.ts │ │ └── transfer_from_multisig.ts │ ├── tensor │ │ ├── cancel_listing.ts │ │ ├── index.ts │ │ └── list_nft.ts │ ├── tiplink │ │ ├── index.ts │ │ └── tiplink.ts │ └── voltr │ │ ├── deposit_strategy.ts │ │ ├── get_position_values.ts │ │ ├── index.ts │ │ └── withdraw_strategy.ts ├── tools │ ├── 3land │ │ ├── create_3land_collectible.ts │ │ └── index.ts │ ├── adrena │ │ ├── adrena_perp_trading.ts │ │ └── index.ts │ ├── agent │ │ ├── create_image.ts │ │ ├── get_info.ts │ │ ├── get_wallet_address.ts │ │ └── index.ts │ ├── alldomains │ │ ├── get_all_domains_tlds.ts │ │ ├── get_owned_all_domains.ts │ │ ├── get_owned_domains_for_tld.ts │ │ ├── index.ts │ │ └── resolve_domain.ts │ ├── allora │ │ ├── get_all_topics.ts │ │ ├── get_inference_by_topic_id.ts │ │ ├── get_price_inference.ts │ │ └── index.ts │ ├── dexscreener │ │ ├── get_token_data.ts │ │ └── index.ts │ ├── drift │ │ ├── drift.ts │ │ ├── drift_vault.ts │ │ ├── index.ts │ │ └── types.ts │ ├── flash │ │ ├── flash_close_trade.ts │ │ ├── flash_open_trade.ts │ │ └── index.ts │ ├── gibwork │ │ ├── create_gibwork_task.ts │ │ └── index.ts │ ├── helius │ │ ├── get_assets_by_owner.ts │ │ ├── helius_transaction_parsing.ts │ │ ├── helius_webhooks.ts │ │ ├── index.ts │ │ └── send_transaction_with_priority.ts │ ├── index.ts │ ├── jupiter │ │ ├── fetch_price.ts │ │ ├── index.ts │ │ ├── stake_with_jup.ts │ │ └── trade.ts │ ├── lightprotocol │ │ ├── index.ts │ │ └── send_compressed_airdrop.ts │ ├── lulo │ │ ├── index.ts │ │ ├── lend.ts │ │ ├── lulo_lend.ts │ │ └── lulo_withdraw.ts │ ├── manifest │ │ ├── index.ts │ │ └── manifest_trade.ts │ ├── metaplex │ │ ├── deploy_collection.ts │ │ ├── deploy_token.ts │ │ ├── get_asset.ts │ │ ├── get_assets_by_authority.ts │ │ ├── get_assets_by_creator.ts │ │ ├── index.ts │ │ └── mint_nft.ts │ ├── meteora │ │ ├── create_meteora_dlmm_pool.ts │ │ ├── create_meteora_dynamic_amm_pool.ts │ │ └── index.ts │ ├── openbook │ │ ├── index.ts │ │ └── openbook_create_market.ts │ ├── orca │ │ ├── index.ts │ │ ├── orca_close_position.ts │ │ ├── orca_create_clmm.ts │ │ ├── orca_create_single_sided_liquidity_pool.ts │ │ ├── orca_fetch_positions.ts │ │ ├── orca_open_centered_position_with_liquidity.ts │ │ └── orca_open_single_sided_position.ts │ ├── pumpfun │ │ ├── index.ts │ │ └── launch_pumpfun_token.ts │ ├── pyth │ │ ├── index.ts │ │ └── pyth_fetch_price.ts │ ├── raydium │ │ ├── index.ts │ │ ├── raydium_create_ammV4.ts │ │ ├── raydium_create_clmm.ts │ │ └── raydium_create_cpmm.ts │ ├── rugcheck │ │ ├── index.ts │ │ └── rugcheck.ts │ ├── sendarcade │ │ ├── index.ts │ │ └── rock_paper_scissor.ts │ ├── sns │ │ ├── get_all_registered_all_domains.ts │ │ ├── get_main_all_domains_domain.ts │ │ ├── get_primary_domain.ts │ │ ├── index.ts │ │ ├── register_domain.ts │ │ └── resolve_sol_domain.ts │ ├── solana │ │ ├── close_empty_token_accounts.ts │ │ ├── get_balance.ts │ │ ├── get_balance_other.ts │ │ ├── get_token_balances.ts │ │ ├── get_tps.ts │ │ ├── index.ts │ │ ├── request_faucet_funds.ts │ │ └── transfer.ts │ ├── solayer │ │ ├── index.ts │ │ └── stake_with_solayer.ts │ ├── squads │ │ ├── approve_proposal.ts │ │ ├── create_multisig.ts │ │ ├── create_proposal.ts │ │ ├── deposit_to_treasury.ts │ │ ├── execute_proposal.ts │ │ ├── index.ts │ │ ├── reject_proposal.ts │ │ └── transfer_from_treasury.ts │ ├── tensor │ │ ├── index.ts │ │ └── tensor_trade.ts │ ├── tiplink │ │ ├── create_tiplinks.ts │ │ └── index.ts │ └── voltr │ │ ├── index.ts │ │ ├── voltr_deposit_strategy.ts │ │ ├── voltr_get_position_values.ts │ │ └── voltr_withdraw_strategy.ts ├── types │ ├── action.ts │ └── index.ts ├── utils │ ├── AdrenaClient.ts │ ├── actionExecutor.ts │ ├── flashUtils.ts │ ├── keypair.ts │ ├── send_tx.ts │ └── tokenMetadata.ts └── vercel-ai │ └── index.ts ├── test ├── agent_sdks │ └── vercel_ai.ts ├── index.ts └── tools │ ├── 3land.ts │ ├── create_meteora_dlmm_pool.ts │ └── create_meteora_dynamic_amm_pool.ts └── tsconfig.json /.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | RPC_URL= 3 | SOLANA_PRIVATE_KEY= 4 | JUPITER_REFERRAL_ACCOUNT= 5 | JUPITER_FEE_BPS= 6 | FLASH_PRIVILEGE= referral | nft | none 7 | FLEXLEND_API_KEY= 8 | HELIUS_API_KEY= 9 | ALLORA_API_KEY= 10 | ALLORA_API_URL= 11 | ALLORA_NETWORK= testnet | mainnet 12 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["@typescript-eslint", "prettier"], 5 | "extends": [ 6 | "eslint:recommended", 7 | "plugin:@typescript-eslint/recommended", 8 | "prettier" 9 | ], 10 | "ignorePatterns": ["examples/**/*", "src/utils/keypair.ts", "test/**/*", "dist/**/*"], 11 | "rules": { 12 | "prettier/prettier": "error", 13 | "no-constant-condition": "off", 14 | "@typescript-eslint/explicit-function-return-type": "off", 15 | "@typescript-eslint/no-explicit-any": "off", 16 | "@typescript-eslint/no-empty-object-type": "off", 17 | "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], 18 | "no-console": ["warn", { "allow": ["warn", "error"] }], 19 | "curly": ["error", "all"], 20 | "eqeqeq": ["error", "always"], 21 | "no-floating-decimal": "error", 22 | "no-var": "error", 23 | "prefer-const": "error" 24 | }, 25 | "env": { 26 | "browser": true, 27 | "node": true, 28 | "es6": true 29 | }, 30 | "parserOptions": { 31 | "ecmaVersion": 2020, 32 | "sourceType": "module" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Pull Request Description 2 | 3 | ## Related Issue 4 | Fixes # (issue number) 5 | 6 | ## Changes Made 7 | This PR adds the following changes: 8 | 9 | - 10 | - 11 | 12 | ## Implementation Details 13 | 14 | - 15 | - 16 | 17 | ## Transaction executed by agent 18 | 19 | Example transaction: 20 | 21 | ## Prompt Used 22 | 23 | ``` 24 | ``` 25 | 26 | ## Additional Notes 27 | 28 | 29 | ## Checklist 30 | - [ ] I have tested these changes locally 31 | - [ ] I have updated the documentation 32 | - [ ] I have added a transaction link 33 | - [ ] I have added the prompt used to test it 34 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: [main] 5 | pull_request: 6 | branches: [main] 7 | jobs: 8 | check: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | 13 | - uses: pnpm/action-setup@v3 14 | with: 15 | version: 9.4.0 16 | 17 | - name: Install node-gyp prerequisites 18 | run: sudo apt update && sudo apt install -y build-essential python3 pkg-config libudev-dev libusb-1.0-0-dev 19 | 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version: "23" 23 | cache: "pnpm" 24 | 25 | - name: Install dependencies 26 | run: pnpm install -r --no-frozen-lockfile 27 | 28 | - name: Run lint and fix 29 | run: pnpm run lint:fix 30 | 31 | - name: Build packages 32 | run: pnpm run build 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .env 4 | 5 | # VSCode 6 | .vscode 7 | 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | tsc && lint-staged -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "**/*.+(ts|tsx)": [ 3 | "eslint . --ext .ts --fix" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | docs 4 | *.md -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": false, 5 | "printWidth": 80, 6 | "tabWidth": 2, 7 | "useTabs": false, 8 | "bracketSpacing": true, 9 | "arrowParens": "always", 10 | "endOfLine": "lf", 11 | "bracketSameLine": false 12 | } -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: Solana Agent Kit 3 | message: >- 4 | If you use this software, please cite it using the 5 | metadata from this file. 6 | type: software 7 | authors: 8 | - name: SendAI 9 | repository-code: 'https://github.com/sendaifun/solana-agent-kit' 10 | url: 'https://github.com/sendaifun/solana-agent-kit' 11 | abstract: >- 12 | Connect any AI Agents to Solana Protocols 13 | keywords: 14 | - solana 15 | - blockchain 16 | - web3 17 | - agent 18 | - toolkit 19 | license: Apache-2.0 20 | version: 1.2.0 21 | preferred-citation: 22 | type: software 23 | title: Solana Agent Kit 24 | abstract: Connect any AI Agents to Solana Protocols 25 | version: 1.2.0 26 | date-released: '2024-12-21' 27 | license: Apache-2.0 28 | url: 'https://github.com/sendaifun/solana-agent-kit' 29 | repository-code: 'https://github.com/sendaifun/solana-agent-kit' 30 | authors: 31 | - name: SendAI 32 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/assets/hierarchy.js: -------------------------------------------------------------------------------- 1 | window.hierarchyData = "eJyrVirKzy8pVrKKjtVRKkpNy0lNLsnMzytWsqqurQUAmx4Kpg==" -------------------------------------------------------------------------------- /docs/assets/navigation.js: -------------------------------------------------------------------------------- 1 | window.navigationData = "eJyNllGTkzAQgP8Lzx3r9bxT+1Zbq+h57dwx3oPjwzZsS4aQMMmi7Tj+d6fQEShh4YUH9ttvYSGb/PgTEB4pmAfPRoGGxQE1fZUUTIIcKAnmgVDgHLppO/4qoUwFkyCVOg7mN7N3fyf/TQtB0ujaIDWh3YNAN61C7eTZ3X0n+eMRslwh47gQnOoDkEg2Nka7BSK0/kfqUJxyaZTCsv4Kc2VOGWryWn3gOPEmP1/dgPVC8Uq9l4cezznEJlsEMtafXcW49DWSSLZWCnxClxvt/J+yi7FSBS5ZKuMwshDjFixk/j55yUH1KOtI4Se5+21sWrYKI3DpE/a3oQ/mCnxGJQv3grvEmDSM2Tb3sKP14+Vj1F+KXBLayKSoV0DgtV5DnPChUGYhhCk0rZBAKsc+cD/OFfkmNdXL73EdsTV6aa7EZQj1/n+NOKfZWmmspNMa+cXn4VhtkeX7Qj9AoUXCi33kkHpd6PJjc+PPw7HaEyUjB5EfHZKX8BoxDlchYdZrvuJGaYeFQ6qyTcsERer11GF2DoCOFTb2ATrl50Vf3b7KfP3+7c3drLmZL6Nw8/hcZ/8CK2Gnzrt4FWobbpvJohyH1bEjMkY1/ol9ocuF5aYdqC28f9MRfkcrUC3CAWULY6R4RFEQXp95al0LYER7qeN+Sx1lFAek1uHI+3odqCP8+Q8guIFL" -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | RPC_URL= 3 | SOLANA_PRIVATE_KEY= 4 | TAVILY_API_KEY= #Optional: for search functionality 5 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | package-lock.json 4 | 5 | # Environment variables 6 | .env 7 | .env.local 8 | 9 | # Build output 10 | dist/ 11 | build/ -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/assets/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abforger/solpython/fe8c1ecb9504672637bf945c4dc74e4f8a0ac517/examples/agent-kit-langgraph/assets/architecture.png -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/langgraph.json: -------------------------------------------------------------------------------- 1 | { 2 | "node_version": "20", 3 | "dockerfile_lines": [], 4 | "dependencies": ["."], 5 | "graphs": { 6 | "solanaAgent": "./src/index.ts:graph" 7 | }, 8 | "env": ".env" 9 | } -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agent-kit-langgraph", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "dev": "tsx" 10 | }, 11 | "dependencies": { 12 | "@langchain/community": "^0.3.20", 13 | "@langchain/core": "^0.3.26", 14 | "@langchain/langgraph": "^0.2.36", 15 | "dotenv": "^16.4.7", 16 | "solana-agent-kit": "^1.3.0", 17 | "zod": "^3.24.1" 18 | }, 19 | "devDependencies": { 20 | "tsx": "^4.19.2", 21 | "typescript": "^5.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/agents/generalAgent.ts: -------------------------------------------------------------------------------- 1 | import { createReactAgent } from "@langchain/langgraph/prebuilt"; 2 | import { gpt4o } from "../utils/model"; 3 | import { solanaAgentState } from "../utils/state"; 4 | import { TavilySearchResults } from "@langchain/community/tools/tavily_search"; 5 | 6 | // Initialize tools array 7 | const searchTools = []; 8 | 9 | // Only add Tavily search if API key is available 10 | if (process.env.TAVILY_API_KEY) { 11 | searchTools.push(new TavilySearchResults()); 12 | } 13 | 14 | const generalAgent = createReactAgent({ 15 | llm: gpt4o, 16 | tools: searchTools, 17 | }); 18 | 19 | export const generalistNode = async (state: typeof solanaAgentState.State) => { 20 | const { messages } = state; 21 | 22 | const result = await generalAgent.invoke({ messages }); 23 | 24 | return { messages: [...result.messages] }; 25 | }; 26 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/agents/manager.ts: -------------------------------------------------------------------------------- 1 | import { prompt, parser } from "../prompts/manager"; 2 | import { RunnableSequence } from "@langchain/core/runnables"; 3 | import { solanaAgentState } from "../utils/state"; 4 | import { gpt4o } from "../utils/model"; 5 | 6 | const chain = RunnableSequence.from([prompt, gpt4o, parser]); 7 | 8 | export const managerNode = async (state: typeof solanaAgentState.State) => { 9 | const { messages } = state; 10 | 11 | const result = await chain.invoke({ 12 | formatInstructions: parser.getFormatInstructions(), 13 | messages: messages, 14 | }); 15 | 16 | const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = result; 17 | 18 | return { 19 | isSolanaReadQuery, 20 | isSolanaWriteQuery, 21 | isGeneralQuery, 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/agents/readAgent.ts: -------------------------------------------------------------------------------- 1 | import { createReactAgent } from "@langchain/langgraph/prebuilt"; 2 | import { gpt4o } from "../utils/model"; 3 | import { solanaAgentState } from "../utils/state"; 4 | import { agentKit } from "../utils/solanaAgent"; 5 | import { 6 | SolanaBalanceTool, 7 | SolanaFetchPriceTool, 8 | } from "solana-agent-kit/dist/langchain"; 9 | 10 | const readAgent = createReactAgent({ 11 | llm: gpt4o, 12 | tools: [new SolanaBalanceTool(agentKit), new SolanaFetchPriceTool(agentKit)], 13 | }); 14 | 15 | export const readNode = async (state: typeof solanaAgentState.State) => { 16 | const { messages } = state; 17 | 18 | const result = await readAgent.invoke({ messages }); 19 | 20 | return { messages: [...result.messages] }; 21 | }; 22 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/agents/transferOrSwap.ts: -------------------------------------------------------------------------------- 1 | import { gpt4o } from "../utils/model"; 2 | import { agentKit } from "../utils/solanaAgent"; 3 | import { solanaAgentState } from "../utils/state"; 4 | import { createReactAgent } from "@langchain/langgraph/prebuilt"; 5 | import { SolanaTransferTool } from "solana-agent-kit/dist/langchain"; 6 | import { transferSwapPrompt } from "../prompts/transferSwap"; 7 | import { swapTool } from "../tools/swap"; 8 | 9 | const transferOrSwapAgent = createReactAgent({ 10 | stateModifier: transferSwapPrompt, 11 | llm: gpt4o, 12 | tools: [new SolanaTransferTool(agentKit), swapTool], 13 | }); 14 | 15 | export const transferSwapNode = async ( 16 | state: typeof solanaAgentState.State, 17 | ) => { 18 | const { messages } = state; 19 | 20 | const result = await transferOrSwapAgent.invoke({ 21 | messages, 22 | }); 23 | 24 | return result; 25 | }; 26 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/helper/examples.ts: -------------------------------------------------------------------------------- 1 | import { HumanMessage } from "@langchain/core/messages"; 2 | 3 | export const generalQuestion = [ 4 | new HumanMessage("Who is the president of Ecuador?"), 5 | ]; 6 | 7 | export const solanaReadQuery = [new HumanMessage("what is the price of SOL")]; 8 | 9 | export const solanaWriteQuery = [new HumanMessage("swap 0.1 usdc to sol")]; 10 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/helper/tokenList.ts: -------------------------------------------------------------------------------- 1 | export const tokenList = [ 2 | { 3 | name: "USDC", 4 | ticker: "USDC", 5 | decimal: 6, 6 | mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", 7 | }, 8 | { 9 | name: "USDT", 10 | ticker: "USDT", 11 | decimal: 6, 12 | mintAddress: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", 13 | }, 14 | { 15 | name: "USDS", 16 | ticker: "USDS", 17 | decimal: 6, 18 | mintAddress: "USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA", 19 | }, 20 | { 21 | name: "SOL", 22 | ticker: "SOL", 23 | decimal: 9, 24 | mintAddress: "So11111111111111111111111111111111111111112", 25 | }, 26 | { 27 | name: "jitoSOL", 28 | ticker: "jitoSOL", 29 | decimal: 9, 30 | mintAddress: "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", 31 | }, 32 | { 33 | name: "bSOL", 34 | ticker: "bSOL", 35 | decimal: 9, 36 | mintAddress: "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1", 37 | }, 38 | { 39 | name: "mSOL", 40 | ticker: "mSOL", 41 | decimal: 9, 42 | mintAddress: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", 43 | }, 44 | { 45 | name: "BONK", 46 | ticker: "BONK", 47 | decimal: 9, 48 | mintAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263", 49 | }, 50 | ]; 51 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/index.ts: -------------------------------------------------------------------------------- 1 | import { StateGraph } from "@langchain/langgraph"; 2 | import { solanaAgentState } from "./utils/state"; 3 | import { generalistNode } from "./agents/generalAgent"; 4 | import { transferSwapNode } from "./agents/transferOrSwap"; 5 | import { managerNode } from "./agents/manager"; 6 | import { readNode } from "./agents/readAgent"; 7 | import { START, END } from "@langchain/langgraph"; 8 | import { managerRouter } from "./utils/route"; 9 | import { HumanMessage } from "@langchain/core/messages"; 10 | 11 | const workflow = new StateGraph(solanaAgentState) 12 | .addNode("generalist", generalistNode) 13 | .addNode("manager", managerNode) 14 | .addNode("transferSwap", transferSwapNode) 15 | .addNode("read", readNode) 16 | .addEdge(START, "manager") 17 | .addConditionalEdges("manager", managerRouter) 18 | .addEdge("generalist", END) 19 | .addEdge("transferSwap", END) 20 | .addEdge("read", END); 21 | 22 | export const graph = workflow.compile(); 23 | 24 | const result = await graph.invoke({ 25 | messages: [new HumanMessage("what is the price of SOL")], 26 | }); 27 | 28 | console.log(result); 29 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/utils/model.ts: -------------------------------------------------------------------------------- 1 | import { ChatOpenAI } from "@langchain/openai"; 2 | import "dotenv/config"; 3 | 4 | export const gpt4o = new ChatOpenAI({ 5 | modelName: "gpt-4o", 6 | apiKey: process.env.OPENAI_API_KEY!, 7 | }); 8 | 9 | export const gpt4oMini = new ChatOpenAI({ 10 | modelName: "gpt-4o-mini", 11 | apiKey: process.env.OPENAI_API_KEY!, 12 | }); 13 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/utils/route.ts: -------------------------------------------------------------------------------- 1 | import { solanaAgentState } from "./state"; 2 | import { END } from "@langchain/langgraph"; 3 | 4 | export const managerRouter = (state: typeof solanaAgentState.State) => { 5 | const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = state; 6 | 7 | if (isGeneralQuery) { 8 | return "generalist"; 9 | } else if (isSolanaWriteQuery) { 10 | return "transferSwap"; 11 | } else if (isSolanaReadQuery) { 12 | return "read"; 13 | } else { 14 | return END; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/utils/solanaAgent.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit"; 2 | 3 | export const agentKit = new SolanaAgentKit( 4 | process.env.SOLANA_PRIVATE_KEY!, 5 | process.env.RPC_URL!, 6 | { OPENAI_API_KEY: process.env.OPENAI_API_KEY! }, 7 | ); 8 | 9 | export const solanaTools = createSolanaTools(agentKit); 10 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/src/utils/state.ts: -------------------------------------------------------------------------------- 1 | import { Annotation } from "@langchain/langgraph"; 2 | import { BaseMessage } from "@langchain/core/messages"; 3 | import { messagesStateReducer } from "@langchain/langgraph"; 4 | 5 | export const solanaAgentState = Annotation.Root({ 6 | messages: Annotation({ 7 | reducer: messagesStateReducer, 8 | default: () => [], 9 | }), 10 | 11 | isSolanaReadQuery: Annotation({ 12 | reducer: (x, y) => y ?? x ?? false, 13 | default: () => false, 14 | }), 15 | 16 | isSolanaWriteQuery: Annotation({ 17 | reducer: (x, y) => y ?? x ?? false, 18 | default: () => false, 19 | }), 20 | 21 | isGeneralQuery: Annotation({ 22 | reducer: (x, y) => y ?? x ?? false, 23 | default: () => false, 24 | }), 25 | }); 26 | -------------------------------------------------------------------------------- /examples/agent-kit-langgraph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "es2022", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "outDir": "./dist" 9 | }, 10 | "include": ["src/**/*"], 11 | "exclude": ["node_modules"] 12 | } -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/.env.example: -------------------------------------------------------------------------------- 1 | LANGCHAIN_CALLBACKS_BACKGROUND=false 2 | OPENAI_API_KEY= 3 | RPC_URL= 4 | SOLANA_PRIVATE_KEY= 5 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | 37 | .yarn/* 38 | !.yarn/patches 39 | !.yarn/plugins 40 | !.yarn/releases 41 | !.yarn/sdks 42 | !.yarn/versions 43 | .env -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/.prettierrc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 LangChain 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. 22 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | color: #f8f8f8; 7 | background: #131318; 8 | } 9 | 10 | body input, 11 | body textarea { 12 | color: black; 13 | } 14 | 15 | a { 16 | color: #2d7bd4; 17 | } 18 | 19 | a:hover { 20 | border-bottom: 1px solid; 21 | } 22 | 23 | p { 24 | margin: 8px 0; 25 | } 26 | 27 | code { 28 | color: #ffa500; 29 | } 30 | 31 | li { 32 | padding: 4px; 33 | } 34 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/next.config.js: -------------------------------------------------------------------------------- 1 | const withBundleAnalyzer = require('@next/bundle-analyzer')({ 2 | enabled: process.env.ANALYZE === 'true', 3 | }) 4 | module.exports = withBundleAnalyzer({}) -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "langchain-nextjs-template", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "format": "prettier --write \"app\"" 11 | }, 12 | "engines": { 13 | "node": ">=18" 14 | }, 15 | "dependencies": { 16 | "@langchain/community": "^0.3.11", 17 | "@langchain/core": "^0.3.17", 18 | "@langchain/langgraph": "^0.2.20", 19 | "@langchain/openai": "^0.3.11", 20 | "@next/bundle-analyzer": "^13.4.19", 21 | "@supabase/supabase-js": "^2.32.0", 22 | "@tailwindcss/typography": "^0.5.15", 23 | "@types/node": "20.12.12", 24 | "@types/react": "18.3.2", 25 | "@types/react-dom": "18.3.0", 26 | "ai": "^3.1.12", 27 | "autoprefixer": "10.4.14", 28 | "eslint": "8.46.0", 29 | "eslint-config-next": "13.4.12", 30 | "isomorphic-dompurify": "^2.19.0", 31 | "langchain": "^0.3.5", 32 | "marked": "^15.0.4", 33 | "next": "^14.2.3", 34 | "postcss": "8.4.27", 35 | "react": "^18.3.1", 36 | "react-dom": "^18.3.1", 37 | "react-toastify": "^9.1.3", 38 | "solana-agent-kit": "^1.3.0", 39 | "tailwindcss": "3.3.3", 40 | "typescript": "5.1.6", 41 | "zod": "^3.22.3", 42 | "zod-to-json-schema": "^3.21.4" 43 | }, 44 | "devDependencies": { 45 | "prettier": "3.0.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/public/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abforger/solpython/fe8c1ecb9504672637bf945c4dc74e4f8a0ac517/examples/agent-kit-nextjs-langchain/public/images/favicon.ico -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/public/images/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abforger/solpython/fe8c1ecb9504672637bf945c4dc74e4f8a0ac517/examples/agent-kit-nextjs-langchain/public/images/og-image.png -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/public/images/title-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abforger/solpython/fe8c1ecb9504672637bf945c4dc74e4f8a0ac517/examples/agent-kit-nextjs-langchain/public/images/title-card.png -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./pages/**/*.{js,ts,jsx,tsx,mdx}", 5 | "./components/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./app/**/*.{js,ts,jsx,tsx,mdx}", 7 | ], 8 | theme: { 9 | extend: { 10 | backgroundImage: { 11 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", 12 | "gradient-conic": 13 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", 14 | }, 15 | }, 16 | }, 17 | plugins: [require("@tailwindcss/typography")], 18 | }; 19 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "bundler", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "plugins": [ 18 | { 19 | "name": "next" 20 | } 21 | ], 22 | "paths": { 23 | "@/*": ["./*"] 24 | } 25 | }, 26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 27 | "exclude": ["node_modules"] 28 | } 29 | -------------------------------------------------------------------------------- /examples/agent-kit-nextjs-langchain/utils/markdownToHTML.ts: -------------------------------------------------------------------------------- 1 | import { marked } from "marked"; 2 | import DOMPurify from "isomorphic-dompurify"; 3 | 4 | interface MarkedOptions { 5 | gfm: boolean; 6 | breaks: boolean; 7 | headerIds: boolean; 8 | mangle: false; 9 | highlight?: (code: string, lang: string) => string; 10 | } 11 | 12 | // Configure marked options 13 | const markedOptions: MarkedOptions = { 14 | gfm: true, // GitHub Flavored Markdown 15 | breaks: true, // Convert \n to
16 | headerIds: true, // Add ids to headers 17 | mangle: false, // Don't escape HTML 18 | highlight: function (code: string, lang: string): string { 19 | // You can add syntax highlighting here if needed 20 | return code; 21 | }, 22 | }; 23 | 24 | marked.setOptions(markedOptions); 25 | 26 | // Basic markdown to HTML conversion with sanitization 27 | export default function markdownToHtml(markdown: string) { 28 | const rawHtml = marked.parse(markdown); 29 | return DOMPurify.sanitize(rawHtml as string); 30 | } 31 | -------------------------------------------------------------------------------- /examples/discord-bot-starter/.env.template: -------------------------------------------------------------------------------- 1 | DISCORD_BOT_TOKEN= 2 | SOLANA_PRIVATE_KEY= 3 | SOLANA_RPC_URL= 4 | OPENAI_API_KEY= 5 | -------------------------------------------------------------------------------- /examples/discord-bot-starter/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | *.log 3 | .DS_Store 4 | 5 | logs/ 6 | node_modules/ 7 | build/ 8 | dist/ 9 | -------------------------------------------------------------------------------- /examples/discord-bot-starter/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "arrowParens": "always", 5 | "printWidth": 120, 6 | "singleQuote": true, 7 | "trailingComma": "all", 8 | "endOfLine": "auto", 9 | "bracketSpacing": true 10 | } 11 | -------------------------------------------------------------------------------- /examples/discord-bot-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord-bot-starter", 3 | "version": "1.0.0", 4 | "description": "Discord bot starter template using the Solana Agent Kit by Send AI", 5 | "main": "index.ts", 6 | "scripts": { 7 | "start": "nodemon ./src/index.ts", 8 | "lint": "eslint -c .eslintrc.js --ext .ts ./src", 9 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"" 10 | }, 11 | "author": "dimitrov-d", 12 | "dependencies": { 13 | "discord.js": "^14.17.2", 14 | "dotenv": "^16.4.7", 15 | "solana-agent-kit": "^1.3.4" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "^22.10.5", 19 | "@typescript-eslint/parser": "8.19.0", 20 | "eslint": "^8.56.0", 21 | "eslint-config-prettier": "^9.1.0", 22 | "eslint-import-resolver-typescript": "^3.7.0", 23 | "eslint-plugin-import": "^2.31.0", 24 | "eslint-plugin-prettier": "^5.2.1", 25 | "eslint-plugin-promise": "^7.2.1", 26 | "eslint-plugin-security": "^3.0.1", 27 | "eslint-plugin-sonarjs": "^3.0.1", 28 | "nodemon": "^3.1.9", 29 | "prettier": "^3.4.2", 30 | "tsconfig-paths": "^4.2.0", 31 | "tsx": "^4.19.2", 32 | "typescript": "^5.7.2" 33 | }, 34 | "nodemonConfig": { 35 | "ext": "*.ts", 36 | "exec": "tsx", 37 | "delay": 1000 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/discord-bot-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "./src", 6 | "outDir": "./build", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "module": "commonjs", 10 | "moduleResolution": "node", 11 | "target": "es2020", 12 | "typeRoots": ["node_modules/@types"], 13 | "lib": ["es2018", "dom", "esnext.asynciterable"], 14 | "plugins": [{ "transform": "typescript-transform-paths" }], 15 | "allowSyntheticDefaultImports": true, 16 | "esModuleInterop": true, 17 | "skipLibCheck": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "resolveJsonModule": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/market-making-agent/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | RPC_URL= 3 | SOLANA_PRIVATE_KEY= -------------------------------------------------------------------------------- /examples/market-making-agent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "market-making-agent", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "main": "ts-node index.ts" 8 | }, 9 | "dependencies": { 10 | "@langchain/langgraph-checkpoint-postgres": "^0.0.2", 11 | "solana-agent-kit": "^1.3.6" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/persistent-agent/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | RPC_URL= 3 | SOLANA_PRIVATE_KEY= 4 | POSTGRES_DB_URL= -------------------------------------------------------------------------------- /examples/persistent-agent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "persistance-agent", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@langchain/langgraph-checkpoint-postgres": "^0.0.2", 14 | "solana-agent-kit": "^1.3.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/README.md: -------------------------------------------------------------------------------- 1 | We have three guides on how you can host Solana Agent Kit as a Telegram bot: 2 | 3 | 1. **Basic TG Bot**: This guide explains how to run a simple Solana Agent Kit on a Telegram bot for a single user. 4 | 5 | 2. **Advanced TG Bot**: This guide includes advanced features such as: 6 | - Storing chat history for each user in a PostgreSQL database. 7 | - Maintaining a unique wallet for each user in a Firebase database. 8 | - Managing the chats of multiple users simultaneously. 9 | 10 | 3. **Group TG Bot**: This example demonstrates how to create a Telegram bot using the Solana Agent Kit by Send AI. It includes advanced features such as: 11 | - Storing chat history for each user in a PostgreSQL database. 12 | - Maintaining a unique wallet for each user in a Firebase database. 13 | - This special bot can be run in Telegram groups and handle private conversations, such as wallet addresses, in private chats. It works in groups, maintains a separate context for each user, responds to each user by tagging them, and can handle multiple requests simultaneously. It will only reply if the bot is tagged in the group or its message is replied to. -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | RPC_URL= 3 | TELEGRAM_BOT_TOKEN= 4 | NEXT_PUBLIC_FIREBASE_API_KEY= 5 | NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN= 6 | NEXT_PUBLIC_FIREBASE_PROJECT_ID= 7 | NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET= 8 | NEXT_PUBLIC_FIREBASE_APP_ID= 9 | NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID= 10 | POSTGRES_LINK= -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | }; 6 | 7 | export default nextConfig; 8 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tg-bot-starter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@langchain/core": "^0.3.26", 13 | "@langchain/langgraph": "^0.2.36", 14 | "@langchain/langgraph-checkpoint-postgres": "^0.0.2", 15 | "@langchain/openai": "^0.3.16", 16 | "firebase": "^11.1.0", 17 | "grammy": "^1.33.0", 18 | "messages": "link:@langchain/core/messages", 19 | "next": "15.1.3", 20 | "prebuilt": "link:@langchain/langgraph/prebuilt", 21 | "react": "^19.0.0", 22 | "react-dom": "^19.0.0", 23 | "solana-agent-kit": "^1.3.0" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^20", 27 | "@types/react": "^19", 28 | "@types/react-dom": "^19", 29 | "postcss": "^8", 30 | "tailwindcss": "^3.4.1", 31 | "typescript": "^5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/public/globe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abforger/solpython/fe8c1ecb9504672637bf945c4dc74e4f8a0ac517/examples/tg-bot-starter/advanced-tg-bot/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --background: #ffffff; 7 | --foreground: #171717; 8 | } 9 | 10 | @media (prefers-color-scheme: dark) { 11 | :root { 12 | --background: #0a0a0a; 13 | --foreground: #ededed; 14 | } 15 | } 16 | 17 | body { 18 | color: var(--foreground); 19 | background: var(--background); 20 | font-family: Arial, Helvetica, sans-serif; 21 | } 22 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const geistSans = Geist({ 6 | variable: "--font-geist-sans", 7 | subsets: ["latin"], 8 | }); 9 | 10 | const geistMono = Geist_Mono({ 11 | variable: "--font-geist-mono", 12 | subsets: ["latin"], 13 | }); 14 | 15 | export const metadata: Metadata = { 16 | title: "Create Next App", 17 | description: "Generated by create next app", 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: Readonly<{ 23 | children: React.ReactNode; 24 | }>) { 25 | return ( 26 | 27 | 30 | {children} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | export default { 4 | content: [ 5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | extend: { 11 | colors: { 12 | background: "var(--background)", 13 | foreground: "var(--foreground)", 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | } satisfies Config; 19 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/advanced-tg-bot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | RPC_URL= 3 | SOLANA_PRIVATE_KEY= 4 | TELEGRAM_BOT_TOKEN= -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/README.md: -------------------------------------------------------------------------------- 1 | # Telegram Bot Starter with Solana Agent Kit 2 | 3 | This example showcases how we can make a telegram bot with the Solana Agent Kit by Send AI. 4 | 5 | ## Quick Deploy 6 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fsendaifun%2Fsolana-agent-kit%2Ftree%2Fmain%2Fexamples%2Ftg-bot-starter&env=OPENAI_API_KEY,RPC_URL,SOLANA_PRIVATE_KEY,TELEGRAM_BOT_TOKEN&project-name=solana-agent-kit&repository-name=sak-yourprojectname) 7 | 8 | ## How to get the telegram bot token 9 | 10 | You can check [here](https://help.zoho.com/portal/en/kb/desk/support-channels/instant-messaging/telegram/articles/telegram-integration-with-zoho-desk#How_to_find_a_token_for_an_existing_Telegram_Bot) how you can obtain a bot token for your telegram bot. 11 | 12 | ## How to setup the project 13 | 14 | - Set env variables 15 | - Run ``` pnpm install ``` 16 | - Run ``` pnpm run dev ``` 17 | - Run ``` ngrok http 3000 ``` 18 | - With the URL you got from ngrok, where your bot is hosted at https://yourUrl.app/api/bot 19 | - Set the webhook by using this command ``` curl https://api.telegram.org/bot/setWebhook?url=https://.app/api/bot ``` or simply clicking on that link. 20 | - You can host it on Vercel too as we have used NextJs in this. 21 | - Once the URL is set successfully, you will see this ``` {"ok":true,"result":true,"description":"Webhook was set"} ``` 22 | 23 | Done!!! Congratulations you just hosted Solana Agent Kit on a Telegram bot. 24 | 25 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | }; 6 | 7 | export default nextConfig; 8 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tg-bot-starter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@langchain/core": "^0.3.26", 13 | "@langchain/langgraph": "^0.2.36", 14 | "@langchain/openai": "^0.3.16", 15 | "grammy": "^1.33.0", 16 | "messages": "link:@langchain/core/messages", 17 | "next": "15.1.3", 18 | "prebuilt": "link:@langchain/langgraph/prebuilt", 19 | "react": "^19.0.0", 20 | "react-dom": "^19.0.0", 21 | "solana-agent-kit": "^1.3.0" 22 | }, 23 | "devDependencies": { 24 | "@types/node": "^20", 25 | "@types/react": "^19", 26 | "@types/react-dom": "^19", 27 | "postcss": "^8", 28 | "tailwindcss": "^3.4.1", 29 | "typescript": "^5" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/public/globe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abforger/solpython/fe8c1ecb9504672637bf945c4dc74e4f8a0ac517/examples/tg-bot-starter/basic-tg-bot/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --background: #ffffff; 7 | --foreground: #171717; 8 | } 9 | 10 | @media (prefers-color-scheme: dark) { 11 | :root { 12 | --background: #0a0a0a; 13 | --foreground: #ededed; 14 | } 15 | } 16 | 17 | body { 18 | color: var(--foreground); 19 | background: var(--background); 20 | font-family: Arial, Helvetica, sans-serif; 21 | } 22 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const geistSans = Geist({ 6 | variable: "--font-geist-sans", 7 | subsets: ["latin"], 8 | }); 9 | 10 | const geistMono = Geist_Mono({ 11 | variable: "--font-geist-mono", 12 | subsets: ["latin"], 13 | }); 14 | 15 | export const metadata: Metadata = { 16 | title: "Create Next App", 17 | description: "Generated by create next app", 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: Readonly<{ 23 | children: React.ReactNode; 24 | }>) { 25 | return ( 26 | 27 | 30 | {children} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | export default { 4 | content: [ 5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | extend: { 11 | colors: { 12 | background: "var(--background)", 13 | foreground: "var(--foreground)", 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | } satisfies Config; 19 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/basic-tg-bot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | RPC_URL= 3 | TELEGRAM_BOT_TOKEN= 4 | NEXT_PUBLIC_FIREBASE_API_KEY= 5 | NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN= 6 | NEXT_PUBLIC_FIREBASE_PROJECT_ID= 7 | NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET= 8 | NEXT_PUBLIC_FIREBASE_APP_ID= 9 | NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID= 10 | POSTGRES_LINK= -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | }; 6 | 7 | export default nextConfig; 8 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tg-bot-starter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@langchain/core": "^0.3.26", 13 | "@langchain/langgraph": "^0.2.36", 14 | "@langchain/langgraph-checkpoint-postgres": "^0.0.2", 15 | "@langchain/openai": "^0.3.16", 16 | "firebase": "^11.1.0", 17 | "grammy": "^1.33.0", 18 | "messages": "link:@langchain/core/messages", 19 | "next": "15.1.3", 20 | "prebuilt": "link:@langchain/langgraph/prebuilt", 21 | "react": "^19.0.0", 22 | "react-dom": "^19.0.0", 23 | "solana-agent-kit": "^1.3.0" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^20", 27 | "@types/react": "^19", 28 | "@types/react-dom": "^19", 29 | "postcss": "^8", 30 | "tailwindcss": "^3.4.1", 31 | "typescript": "^5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/public/globe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abforger/solpython/fe8c1ecb9504672637bf945c4dc74e4f8a0ac517/examples/tg-bot-starter/group-tg-bot/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --background: #ffffff; 7 | --foreground: #171717; 8 | } 9 | 10 | @media (prefers-color-scheme: dark) { 11 | :root { 12 | --background: #0a0a0a; 13 | --foreground: #ededed; 14 | } 15 | } 16 | 17 | body { 18 | color: var(--foreground); 19 | background: var(--background); 20 | font-family: Arial, Helvetica, sans-serif; 21 | } 22 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const geistSans = Geist({ 6 | variable: "--font-geist-sans", 7 | subsets: ["latin"], 8 | }); 9 | 10 | const geistMono = Geist_Mono({ 11 | variable: "--font-geist-mono", 12 | subsets: ["latin"], 13 | }); 14 | 15 | export const metadata: Metadata = { 16 | title: "Create Next App", 17 | description: "Generated by create next app", 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: Readonly<{ 23 | children: React.ReactNode; 24 | }>) { 25 | return ( 26 | 27 | 30 | {children} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | export default { 4 | content: [ 5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | extend: { 11 | colors: { 12 | background: "var(--background)", 13 | foreground: "var(--foreground)", 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | } satisfies Config; 19 | -------------------------------------------------------------------------------- /examples/tg-bot-starter/group-tg-bot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /src/actions/agent/getWalletAddress.ts: -------------------------------------------------------------------------------- 1 | import { Action } from "../../types/action"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { z } from "zod"; 4 | import { get_wallet_address } from "../../tools/agent"; 5 | 6 | const getWalletAddressAction: Action = { 7 | name: "GET_WALLET_ADDRESS", 8 | similes: ["wallet address", "address", "wallet"], 9 | description: "Get wallet address of the agent", 10 | examples: [ 11 | [ 12 | { 13 | input: {}, 14 | output: { 15 | status: "success", 16 | address: "0x1234567890abcdef", 17 | }, 18 | explanation: "The agent's wallet address is 0x1234567890abcdef", 19 | }, 20 | ], 21 | ], 22 | schema: z.object({}), 23 | handler: async (agent: SolanaAgentKit) => ({ 24 | status: "success", 25 | address: get_wallet_address(agent), 26 | }), 27 | }; 28 | 29 | export default getWalletAddressAction; 30 | -------------------------------------------------------------------------------- /src/actions/alldomains/resolveDomain.ts: -------------------------------------------------------------------------------- 1 | import { Action } from "../../types/action"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { z } from "zod"; 4 | import { resolveAllDomains } from "../../tools"; 5 | 6 | const resolveDomainAction: Action = { 7 | name: "RESOLVE_ALL_DOMAINS", 8 | similes: [ 9 | "resolve domain", 10 | "lookup domain", 11 | "get domain owner", 12 | "check domain", 13 | "find domain owner", 14 | ], 15 | description: "Resolve a Solana domain name to get its owner's public key", 16 | examples: [ 17 | [ 18 | { 19 | input: { 20 | domain: "example.sol", 21 | }, 22 | output: { 23 | status: "success", 24 | owner: "7nxQB...", 25 | }, 26 | explanation: "Resolve a .sol domain name to get the owner's public key", 27 | }, 28 | ], 29 | ], 30 | schema: z.object({ 31 | domain: z.string().min(1).describe("The domain name to resolve"), 32 | }), 33 | handler: async (agent: SolanaAgentKit, input: Record) => { 34 | try { 35 | const domain = input.domain as string; 36 | const tld = await resolveAllDomains(agent, domain); 37 | return { 38 | status: "success", 39 | owner: tld, 40 | message: `Successfully resolved domain ${domain}`, 41 | }; 42 | } catch (error: any) { 43 | return { 44 | status: "error", 45 | message: `Failed to resolve domain: ${error.message}`, 46 | }; 47 | } 48 | }, 49 | }; 50 | 51 | export default resolveDomainAction; 52 | -------------------------------------------------------------------------------- /src/actions/drift/deriveVaultAddress.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import type { Action } from "../../types"; 3 | import { getVaultAddress } from "../../tools"; 4 | 5 | const deriveDriftVaultAddressAction: Action = { 6 | name: "DERIVE_DRIFT_VAULT_ADDRESS_ACTION", 7 | similes: ["derive drift vault address", "get drift vault address"], 8 | description: "Derive a drift vault address from the vaults name", 9 | examples: [ 10 | [ 11 | { 12 | input: { 13 | name: "My Drift Vault", 14 | }, 15 | output: { 16 | status: "success", 17 | message: "Vault address derived successfully", 18 | address: "2nFeP7taii3wGVgrWk4YiLMPmhtu3Zg9iXCUu4zGBD", 19 | }, 20 | explanation: "Derive a drift vault address", 21 | }, 22 | ], 23 | ], 24 | schema: z.object({ 25 | name: z.string().describe("The name of the vault to derive the address of"), 26 | }), 27 | handler: async (agent, input) => { 28 | try { 29 | const address = await getVaultAddress(agent, input.name as string); 30 | 31 | return { 32 | status: "success", 33 | message: "Vault address derived successfully", 34 | address, 35 | }; 36 | } catch (e) { 37 | return { 38 | status: "error", 39 | // @ts-expect-error - error message 40 | message: `Failed to derive vault address: ${e.message}`, 41 | }; 42 | } 43 | }, 44 | }; 45 | 46 | export default deriveDriftVaultAddressAction; 47 | -------------------------------------------------------------------------------- /src/actions/drift/driftUserAccountInfo.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import type { Action } from "../../types"; 3 | import { driftUserAccountInfo } from "../../tools"; 4 | 5 | const driftUserAccountInfoAction: Action = { 6 | name: "DRIFT_USER_ACCOUNT_INFO", 7 | similes: ["get drift user account info", "get drift account info"], 8 | description: "Get information about your drift account", 9 | examples: [ 10 | [ 11 | { 12 | input: {}, 13 | explanation: "Get information about your drift account", 14 | output: { 15 | status: "success", 16 | data: {}, 17 | }, 18 | }, 19 | ], 20 | ], 21 | schema: z.object({}), 22 | handler: async (agent) => { 23 | try { 24 | const accountInfo = await driftUserAccountInfo(agent); 25 | return { 26 | status: "success", 27 | data: accountInfo, 28 | }; 29 | } catch (e) { 30 | return { 31 | status: "error", 32 | // @ts-expect-error - error message is a string 33 | message: `Failed to get drift account info: ${e.message}`, 34 | }; 35 | } 36 | }, 37 | }; 38 | 39 | export default driftUserAccountInfoAction; 40 | -------------------------------------------------------------------------------- /src/actions/helius/deleteWebhook.ts: -------------------------------------------------------------------------------- 1 | import { Action } from "../../types/action"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { z } from "zod"; 4 | import { deleteHeliusWebhook } from "../../tools/helius"; 5 | 6 | const deleteWebhookAction: Action = { 7 | name: "DELETE_HELIOUS_WEBHOOK", 8 | similes: ["remove webhook", "unregister webhook", "delete webhook"], 9 | description: "Deletes a Helius webhook by its unique ID", 10 | examples: [ 11 | [ 12 | { 13 | input: { 14 | webhookID: "webhook_123", 15 | }, 16 | output: { 17 | status: "success", 18 | message: "Webhook deleted successfully.", 19 | }, 20 | explanation: "Permanently removes a Helius webhook.", 21 | }, 22 | ], 23 | ], 24 | schema: z.object({ 25 | webhookID: z 26 | .string() 27 | .min(1) 28 | .describe("The unique identifier of the Helius webhook to delete"), 29 | }), 30 | handler: async (agent: SolanaAgentKit, input: Record) => { 31 | const result = await deleteHeliusWebhook(agent, input.webhookID); 32 | 33 | return { 34 | status: "success", 35 | message: result.message || "Webhook deleted successfully.", 36 | }; 37 | }, 38 | }; 39 | 40 | export default deleteWebhookAction; 41 | -------------------------------------------------------------------------------- /src/actions/lulo/lendAsset.ts: -------------------------------------------------------------------------------- 1 | import { Action } from "../../types/action"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { z } from "zod"; 4 | import { lendAsset } from "../../tools/lulo"; 5 | 6 | const lendAssetAction: Action = { 7 | name: "LEND_ASSET", 8 | similes: [ 9 | "lend usdc", 10 | "deposit for yield", 11 | "earn yield", 12 | "lend with lulo", 13 | "deposit usdc", 14 | "lending", 15 | ], 16 | description: "Lend USDC tokens to earn yield using Lulo protocol", 17 | examples: [ 18 | [ 19 | { 20 | input: { 21 | amount: 100, 22 | }, 23 | output: { 24 | status: "success", 25 | signature: "4xKpN2...", 26 | message: "Successfully lent 100 USDC", 27 | }, 28 | explanation: "Lend 100 USDC to earn yield on Lulo", 29 | }, 30 | ], 31 | ], 32 | schema: z.object({ 33 | amount: z.number().positive().describe("Amount of USDC to lend"), 34 | }), 35 | handler: async (agent: SolanaAgentKit, input: Record) => { 36 | try { 37 | const amount = input.amount as number; 38 | 39 | const response = await lendAsset(agent, amount); 40 | 41 | return { 42 | status: "success", 43 | signature: response, 44 | message: `Successfully lent ${amount} USDC`, 45 | }; 46 | } catch (error: any) { 47 | return { 48 | status: "error", 49 | message: `Lending failed: ${error.message}`, 50 | }; 51 | } 52 | }, 53 | }; 54 | 55 | export default lendAssetAction; 56 | -------------------------------------------------------------------------------- /src/actions/metaplex/getAsset.ts: -------------------------------------------------------------------------------- 1 | import { Action } from "../../types/action"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { z } from "zod"; 4 | import { get_asset } from "../../tools/metaplex"; 5 | 6 | const getAssetAction: Action = { 7 | name: "GET_ASSET", 8 | similes: [ 9 | "fetch asset", 10 | "retrieve asset", 11 | "get asset details", 12 | "fetch asset details", 13 | ], 14 | description: `Fetch asset details using the Metaplex DAS API.`, 15 | examples: [ 16 | [ 17 | { 18 | input: { 19 | assetId: "Asset ID", 20 | }, 21 | output: { 22 | status: "success", 23 | message: "Asset retrieved successfully", 24 | result: { 25 | // Example asset details 26 | name: "Example Asset", 27 | symbol: "EXA", 28 | uri: "https://example.com/asset.json", 29 | }, 30 | }, 31 | explanation: "Fetch details of an asset using its ID", 32 | }, 33 | ], 34 | ], 35 | schema: z.object({ 36 | assetId: z.string().min(1, "Asset ID is required"), 37 | }), 38 | handler: async (agent: SolanaAgentKit, input: Record) => { 39 | const assetId = input.assetId; 40 | 41 | const result = await get_asset(agent, assetId); 42 | 43 | return { 44 | status: "success", 45 | message: "Asset retrieved successfully", 46 | result, 47 | }; 48 | }, 49 | }; 50 | 51 | export default getAssetAction; 52 | -------------------------------------------------------------------------------- /src/actions/solana/getTPS.ts: -------------------------------------------------------------------------------- 1 | import { Action } from "../../types/action"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { z } from "zod"; 4 | import { getTPS } from "../../tools/solana"; 5 | 6 | const getTPSAction: Action = { 7 | name: "GET_TPS", 8 | similes: [ 9 | "get transactions per second", 10 | "check network speed", 11 | "network performance", 12 | "transaction throughput", 13 | "network tps", 14 | ], 15 | description: 16 | "Get the current transactions per second (TPS) of the Solana network", 17 | examples: [ 18 | [ 19 | { 20 | input: {}, 21 | output: { 22 | status: "success", 23 | tps: 3500, 24 | message: "Current network TPS: 3500", 25 | }, 26 | explanation: "Get the current TPS of the Solana network", 27 | }, 28 | ], 29 | ], 30 | schema: z.object({}), // No input parameters required 31 | handler: async (agent: SolanaAgentKit, _input: Record) => { 32 | try { 33 | const response = await getTPS(agent); 34 | return { 35 | status: "success", 36 | response, 37 | message: `Current network TPS: ${response}`, 38 | }; 39 | } catch (error: any) { 40 | return { 41 | status: "error", 42 | message: `Failed to get TPS: ${error.message}`, 43 | }; 44 | } 45 | }, 46 | }; 47 | 48 | export default getTPSAction; 49 | -------------------------------------------------------------------------------- /src/actions/solana/requestFunds.ts: -------------------------------------------------------------------------------- 1 | import { Action } from "../../types/action"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { z } from "zod"; 4 | import { request_faucet_funds } from "../../tools/solana"; 5 | 6 | const requestFundsAction: Action = { 7 | name: "REQUEST_FUNDS", 8 | similes: [ 9 | "request sol", 10 | "get test sol", 11 | "use faucet", 12 | "request test tokens", 13 | "get devnet sol", 14 | ], 15 | description: "Request SOL from Solana faucet (devnet/testnet only)", 16 | examples: [ 17 | [ 18 | { 19 | input: {}, 20 | output: { 21 | status: "success", 22 | message: "Successfully requested faucet funds", 23 | network: "devnet.solana.com", 24 | }, 25 | explanation: "Request SOL from the devnet faucet", 26 | }, 27 | ], 28 | ], 29 | schema: z.object({}), // No input parameters required 30 | handler: async (agent: SolanaAgentKit, _input: Record) => { 31 | await request_faucet_funds(agent); 32 | 33 | return { 34 | status: "success", 35 | message: "Successfully requested faucet funds", 36 | network: agent.connection.rpcEndpoint.split("/")[2], 37 | }; 38 | }, 39 | }; 40 | 41 | export default requestFundsAction; 42 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "./agent"; 2 | import { createSolanaTools } from "./langchain"; 3 | import { createSolanaTools as createVercelAITools } from "./vercel-ai"; 4 | 5 | export { SolanaAgentKit, createSolanaTools, createVercelAITools }; 6 | 7 | // Optional: Export types that users might need 8 | export * from "./types"; 9 | 10 | // Export action system 11 | export { ACTIONS } from "./actions"; 12 | export * from "./utils/actionExecutor"; 13 | -------------------------------------------------------------------------------- /src/langchain/3land/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_single"; 2 | export * from "./create_collection"; 3 | -------------------------------------------------------------------------------- /src/langchain/adrena/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./open_trade"; 2 | export * from "./close_trade"; 3 | -------------------------------------------------------------------------------- /src/langchain/agent/create_image.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { create_image } from "../../tools/agent"; 4 | 5 | export class SolanaCreateImageTool extends Tool { 6 | name = "solana_create_image"; 7 | description = 8 | "Create an image using OpenAI's DALL-E. Input should be a string prompt for the image."; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | private validateInput(input: string): void { 15 | if (typeof input !== "string" || input.trim().length === 0) { 16 | throw new Error("Input must be a non-empty string prompt"); 17 | } 18 | } 19 | 20 | protected async _call(input: string): Promise { 21 | try { 22 | this.validateInput(input); 23 | const result = await create_image(this.solanaKit, input.trim()); 24 | 25 | return JSON.stringify({ 26 | status: "success", 27 | message: "Image created successfully", 28 | ...result, 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "UNKNOWN_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/agent/get_info.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { get_info } from "../../tools/agent"; 4 | 5 | export class SolanaGetInfoTool extends Tool { 6 | name = "solana_get_info"; 7 | description = 8 | "Get detailed and latest information about any topic using Perplexity AI. Input should be a question or topic to get information about."; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | private validateInput(input: string): void { 15 | if (typeof input !== "string" || input.trim().length === 0) { 16 | throw new Error("Input must be a non-empty string question"); 17 | } 18 | } 19 | 20 | protected async _call(input: string): Promise { 21 | try { 22 | this.validateInput(input); 23 | const result = await get_info(this.solanaKit, input.trim()); 24 | 25 | return JSON.stringify({ 26 | status: "success", 27 | message: "Information retrieved successfully", 28 | content: result, 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "UNKNOWN_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/agent/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_image"; 2 | export * from "./wallet_address"; 3 | export * from "./get_info"; 4 | -------------------------------------------------------------------------------- /src/langchain/agent/wallet_address.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaGetWalletAddressTool extends Tool { 5 | name = "solana_get_wallet_address"; 6 | description = `Get the wallet address of the agent`; 7 | 8 | constructor(private solanaKit: SolanaAgentKit) { 9 | super(); 10 | } 11 | 12 | async _call(_input: string): Promise { 13 | return this.solanaKit.wallet_address.toString(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/langchain/alldomains/get_all_tld.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaGetAllTlds extends Tool { 5 | name = "solana_get_all_tlds"; 6 | description = `Get all active top-level domains (TLDs) in the AllDomains Name Service`; 7 | 8 | constructor(private solanaKit: SolanaAgentKit) { 9 | super(); 10 | } 11 | 12 | async _call(): Promise { 13 | try { 14 | const tlds = await this.solanaKit.getAllDomainsTLDs(); 15 | 16 | return JSON.stringify({ 17 | status: "success", 18 | message: "TLDs fetched successfully", 19 | tlds, 20 | }); 21 | } catch (error: any) { 22 | return JSON.stringify({ 23 | status: "error", 24 | message: error.message, 25 | code: error.code || "FETCH_TLDS_ERROR", 26 | }); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/langchain/alldomains/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./resolve_all_domains"; 2 | export * from "./owned_domains"; 3 | export * from "./tld_domains"; 4 | export * from "./get_all_tld"; 5 | -------------------------------------------------------------------------------- /src/langchain/alldomains/owned_domains.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaGetOwnedDomains extends Tool { 6 | name = "solana_get_owned_domains"; 7 | description = `Get all domains owned by a specific wallet address. 8 | 9 | Inputs: 10 | owner: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | async _call(input: string): Promise { 17 | try { 18 | const ownerPubkey = new PublicKey(input.trim()); 19 | const domains = await this.solanaKit.getOwnedAllDomains(ownerPubkey); 20 | 21 | return JSON.stringify({ 22 | status: "success", 23 | message: "Owned domains fetched successfully", 24 | domains, 25 | }); 26 | } catch (error: any) { 27 | return JSON.stringify({ 28 | status: "error", 29 | message: error.message, 30 | code: error.code || "FETCH_OWNED_DOMAINS_ERROR", 31 | }); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/langchain/alldomains/resolve_all_domains.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaResolveAllDomainsTool extends Tool { 5 | name = "solana_resolve_all_domains"; 6 | description = `Resolve domain names to a public key for ALL domain types EXCEPT .sol domains. 7 | Use this for domains like .blink, .bonk, etc. 8 | DO NOT use this for .sol domains (use solana_resolve_domain instead). 9 | 10 | Input: 11 | domain: string, eg "mydomain.blink" or "mydomain.bonk" (required)`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | async _call(input: string): Promise { 18 | try { 19 | const owner = await this.solanaKit.resolveAllDomains(input); 20 | 21 | if (!owner) { 22 | return JSON.stringify({ 23 | status: "error", 24 | message: "Domain not found", 25 | code: "DOMAIN_NOT_FOUND", 26 | }); 27 | } 28 | 29 | return JSON.stringify({ 30 | status: "success", 31 | message: "Domain resolved successfully", 32 | owner: owner?.toString(), 33 | }); 34 | } catch (error: any) { 35 | return JSON.stringify({ 36 | status: "error", 37 | message: error.message, 38 | code: error.code || "DOMAIN_RESOLUTION_ERROR", 39 | }); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/langchain/alldomains/tld_domains.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaGetOwnedTldDomains extends Tool { 5 | name = "solana_get_owned_tld_domains"; 6 | description = `Get all domains owned by the agent's wallet for a specific TLD. 7 | 8 | Inputs: 9 | tld: string, eg "bonk" (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | async _call(input: string): Promise { 16 | try { 17 | const domains = await this.solanaKit.getOwnedDomainsForTLD(input); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: "TLD domains fetched successfully", 22 | domains, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "FETCH_TLD_DOMAINS_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/allora/get_all_topics.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { AlloraGetAllTopicsResponse } from "../../index"; 4 | 5 | export class SolanaAlloraGetAllTopics extends Tool { 6 | name = "solana_allora_get_all_topics"; 7 | description = `Get all topics from Allora's API 8 | 9 | Inputs: None`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | async _call(_: string): Promise { 16 | try { 17 | const topics = await this.solanaKit.getAllTopics(); 18 | 19 | const response: AlloraGetAllTopicsResponse = { 20 | status: "success", 21 | message: "Topics fetched successfully", 22 | topics, 23 | }; 24 | 25 | return JSON.stringify(response); 26 | } catch (error: any) { 27 | const response: AlloraGetAllTopicsResponse = { 28 | status: "error", 29 | message: error.message, 30 | code: error.code || "UNKNOWN_ERROR", 31 | }; 32 | return JSON.stringify(response); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/allora/get_inference_by_topic_id.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { AlloraGetInferenceByTopicIdResponse } from "../../types"; 4 | 5 | export class SolanaAlloraGetInferenceByTopicId extends Tool { 6 | name = "solana_allora_get_inference_by_topic_id"; 7 | description = `Get the inference for a given topic ID from Allora's API 8 | Inputs: 9 | topicId: number as a string, e.g., "42"`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | async _call(input: string): Promise { 16 | try { 17 | const topicId = Number(input); 18 | 19 | const inference = await this.solanaKit.getInferenceByTopicId(topicId); 20 | 21 | const response: AlloraGetInferenceByTopicIdResponse = { 22 | status: "success", 23 | message: "Inference fetched successfully", 24 | topicId, 25 | inference, 26 | }; 27 | 28 | return JSON.stringify(response); 29 | } catch (error: any) { 30 | const response: AlloraGetInferenceByTopicIdResponse = { 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "UNKNOWN_ERROR", 34 | }; 35 | return JSON.stringify(response); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/allora/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_price_inference"; 2 | export * from "./get_inference_by_topic_id"; 3 | export * from "./get_all_topics"; 4 | -------------------------------------------------------------------------------- /src/langchain/dexscreener/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./token_data_ticker"; 2 | -------------------------------------------------------------------------------- /src/langchain/dexscreener/token_data_ticker.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaTokenDataByTickerTool extends Tool { 5 | name = "solana_token_data_by_ticker"; 6 | description = `Get the token data for a given token ticker 7 | 8 | Inputs: ticker is required. 9 | ticker: string, eg "USDC" (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const ticker = input.trim(); 18 | const tokenData = await this.solanaKit.getTokenDataByTicker(ticker); 19 | return JSON.stringify({ 20 | status: "success", 21 | tokenData, 22 | }); 23 | } catch (error: any) { 24 | return JSON.stringify({ 25 | status: "error", 26 | message: error.message, 27 | code: error.code || "UNKNOWN_ERROR", 28 | }); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/langchain/drift/create_user_account.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaCreateDriftUserAccountTool extends Tool { 5 | name = "create_drift_user_account"; 6 | description = `Create a new user account with a deposit on Drift protocol. 7 | 8 | Inputs (JSON string): 9 | - amount: number, amount of the token to deposit (required) 10 | - symbol: string, symbol of the token to deposit (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | const res = await this.solanaKit.createDriftUserAccount( 20 | parsedInput.amount, 21 | parsedInput.symbol, 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: `User account created with ${parsedInput.amount} ${parsedInput.symbol} successfully deposited`, 27 | account: res.account, 28 | signature: res.txSignature, 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "CREATE_DRIFT_USER_ACCOUNT_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/drift/deposit_into_vault.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDepositIntoDriftVaultTool extends Tool { 5 | name = "deposit_into_drift_vault"; 6 | description = `Deposit funds into an existing drift vault. 7 | 8 | Inputs (JSON string): 9 | - vaultAddress: string, address of the vault (required) 10 | - amount: number, amount to deposit (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | const tx = await this.solanaKit.depositIntoDriftVault( 20 | parsedInput.amount, 21 | parsedInput.vaultAddress, 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "Funds deposited successfully", 27 | signature: tx, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "DEPOSIT_INTO_VAULT_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/drift/deposit_to_user_account.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDepositToDriftUserAccountTool extends Tool { 5 | name = "deposit_to_drift_user_account"; 6 | description = `Deposit funds into your drift user account. 7 | 8 | Inputs (JSON string): 9 | - amount: number, amount to deposit (required) 10 | - symbol: string, token symbol (required) 11 | - repay: boolean, whether to repay borrowed funds (optional, default: false)`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const parsedInput = JSON.parse(input); 20 | const tx = await this.solanaKit.depositToDriftUserAccount( 21 | parsedInput.amount, 22 | parsedInput.symbol, 23 | parsedInput.repay, 24 | ); 25 | 26 | return JSON.stringify({ 27 | status: "success", 28 | message: "Funds deposited successfully", 29 | signature: tx, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "DEPOSIT_TO_DRIFT_ACCOUNT_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/drift/derive_vault_address.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDeriveVaultAddressTool extends Tool { 5 | name = "derive_drift_vault_address"; 6 | description = `Derive a drift vault address from the vault's name. 7 | 8 | Inputs (JSON string): 9 | - name: string, name of the vault to derive the address of (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const address = await this.solanaKit.deriveDriftVaultAddress(input); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: "Vault address derived successfully", 22 | address, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "DERIVE_VAULT_ADDRESS_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/drift/does_user_have_drift_account.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaCheckDriftAccountTool extends Tool { 5 | name = "does_user_have_drift_account"; 6 | description = `Check if a user has a Drift account. 7 | 8 | Inputs: No inputs required - checks the current user's account`; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | protected async _call(_input: string): Promise { 15 | try { 16 | const res = await this.solanaKit.doesUserHaveDriftAccount(); 17 | 18 | if (!res.hasAccount) { 19 | return JSON.stringify({ 20 | status: "error", 21 | message: "You do not have a Drift account", 22 | }); 23 | } 24 | 25 | return JSON.stringify({ 26 | status: "success", 27 | message: "Nice! You have a Drift account", 28 | account: res.account, 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "CHECK_DRIFT_ACCOUNT_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/drift/drift_user_account_info.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDriftUserAccountInfoTool extends Tool { 5 | name = "drift_user_account_info"; 6 | description = `Get information about your drift account. 7 | 8 | Inputs: No inputs required - retrieves current user's account info`; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | protected async _call(_input: string): Promise { 15 | try { 16 | const accountInfo = await this.solanaKit.driftUserAccountInfo(); 17 | return JSON.stringify({ 18 | status: "success", 19 | data: accountInfo, 20 | }); 21 | } catch (error: any) { 22 | return JSON.stringify({ 23 | status: "error", 24 | message: error.message, 25 | code: error.code || "DRIFT_ACCOUNT_INFO_ERROR", 26 | }); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/langchain/drift/entry_quote_of_perp_trade.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import type { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDriftEntryQuoteOfPerpTradeTool extends Tool { 5 | name = "drift_entry_quote_of_perp_trade"; 6 | description = `Get an entry quote for a perpetual trade on Drift protocol. 7 | 8 | Inputs (JSON string): 9 | - amount: number, amount to trade (required) 10 | - symbol: string, market symbol (required) 11 | - action: "long" | "short", trade direction (required)`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const parsedInput = JSON.parse(input); 20 | const quote = await this.solanaKit.getEntryQuoteOfPerpTrade( 21 | parsedInput.amount, 22 | parsedInput.symbol, 23 | parsedInput.action, 24 | ); 25 | 26 | return JSON.stringify({ 27 | status: "success", 28 | message: `Entry quote retrieved for ${parsedInput.action} ${parsedInput.amount} ${parsedInput.symbol}`, 29 | data: quote, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "ENTRY_QUOTE_OF_PERP_TRADE_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/drift/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_user_account"; 2 | export * from "./create_vault"; 3 | export * from "./deposit_into_vault"; 4 | export * from "./deposit_to_user_account"; 5 | export * from "./derive_vault_address"; 6 | export * from "./does_user_have_drift_account"; 7 | export * from "./drift_user_account_info"; 8 | export * from "./request_withdrawal"; 9 | export * from "./trade_delegated_vault"; 10 | export * from "./trade_perp_account"; 11 | export * from "./update_drift_vault_delegate"; 12 | export * from "./update_vault"; 13 | export * from "./vault_info"; 14 | export * from "./withdraw_from_account"; 15 | export * from "./withdraw_from_vault"; 16 | export * from "./perp_market_funding_rate"; 17 | export * from "./entry_quote_of_perp_trade"; 18 | export * from "./lend_and_borrow_apy"; 19 | export * from "./stake_to_insurance_fund"; 20 | export * from "./swap_spot_token"; 21 | export * from "./unstake_from_insurance_fund"; 22 | export * from "./request_unstake_from_insurance_fund"; 23 | -------------------------------------------------------------------------------- /src/langchain/drift/lend_and_borrow_apy.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import type { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDriftLendAndBorrowAPYTool extends Tool { 5 | name = "drift_lend_and_borrow_apy"; 6 | description = `Get lending and borrowing APY for a token on Drift protocol. 7 | 8 | Inputs (JSON string): 9 | - symbol: string, token symbol (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const apyInfo = await this.solanaKit.getLendAndBorrowAPY(input); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: `APY information retrieved for ${input}`, 22 | data: apyInfo, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "LEND_AND_BORROW_APY_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/drift/perp_market_funding_rate.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import type { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDriftPerpMarketFundingRateTool extends Tool { 5 | name = "drift_perp_market_funding_rate"; 6 | description = `Get the funding rate for a perpetual market on Drift protocol. 7 | 8 | Inputs (JSON string): 9 | - symbol: string, market symbol (required) 10 | - period: year or hour (default: hour)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | const fundingRate = await this.solanaKit.getPerpMarketFundingRate( 20 | parsedInput.symbol, 21 | parsedInput.period, 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: `Funding rate retrieved for ${parsedInput.symbol}`, 27 | data: fundingRate, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | }); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/langchain/drift/request_unstake_from_insurance_fund.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import type { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaRequestUnstakeFromDriftInsuranceFundTool extends Tool { 5 | name = "request_unstake_from_drift_insurance_fund"; 6 | description = `Request to unstake tokens from Drift Insurance Fund. 7 | 8 | Inputs (JSON string): 9 | - amount: number, amount to unstake (required) 10 | - symbol: string, token symbol (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | const tx = await this.solanaKit.requestUnstakeFromDriftInsuranceFund( 20 | parsedInput.amount, 21 | parsedInput.symbol, 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: `Requested unstake of ${parsedInput.amount} ${parsedInput.symbol} from the Drift Insurance Fund`, 27 | signature: tx, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "REQUEST_UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/drift/request_withdrawal.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaRequestDriftWithdrawalTool extends Tool { 5 | name = "request_withdrawal_from_drift_vault"; 6 | description = `Request a withdrawal from an existing drift vault. 7 | 8 | Inputs (JSON string): 9 | - vaultAddress: string, vault address (required) 10 | - amount: number, amount of shares to withdraw (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | const tx = await this.solanaKit.requestWithdrawalFromDriftVault( 20 | parsedInput.amount, 21 | parsedInput.vaultAddress, 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "Withdrawal request successful", 27 | signature: tx, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "REQUEST_DRIFT_WITHDRAWAL_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/drift/stake_to_insurance_fund.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import type { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaStakeToDriftInsuranceFundTool extends Tool { 5 | name = "stake_to_drift_insurance_fund"; 6 | description = `Stake a token to Drift Insurance Fund. 7 | 8 | Inputs (JSON string): 9 | - amount: number, amount to stake (required) 10 | - symbol: string, token symbol (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | const tx = await this.solanaKit.stakeToDriftInsuranceFund( 20 | parsedInput.amount, 21 | parsedInput.symbol, 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: `Staked ${parsedInput.amount} ${parsedInput.symbol} to the Drift Insurance Fund`, 27 | signature: tx, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "STAKE_TO_DRIFT_INSURANCE_FUND_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/drift/swap_spot_token.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import type { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDriftSpotTokenSwapTool extends Tool { 5 | name = "drift_spot_token_swap"; 6 | description = `Swap spot tokens on Drift protocol. 7 | 8 | Inputs (JSON string): 9 | - fromSymbol: string, symbol of token to swap from (required) 10 | - toSymbol: string, symbol of token to swap to (required) 11 | - fromAmount: number, amount to swap from (optional) required if toAmount is not provided 12 | - toAmount: number, amount to swap to (optional) required if fromAmount is not provided 13 | - slippage: number, slippage tolerance in percentage (optional)`; 14 | 15 | constructor(private solanaKit: SolanaAgentKit) { 16 | super(); 17 | } 18 | 19 | protected async _call(input: string): Promise { 20 | try { 21 | const parsedInput = JSON.parse(input); 22 | const tx = await this.solanaKit.driftSpotTokenSwap(parsedInput); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: `Swapped ${parsedInput.fromAmount} ${parsedInput.fromSymbol} for ${parsedInput.toSymbol}`, 27 | signature: tx, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "DRIFT_SPOT_TOKEN_SWAP_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/drift/trade_perp_account.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaTradeDriftPerpAccountTool extends Tool { 5 | name = "trade_drift_perp_account"; 6 | description = `Trade a perpetual account on Drift protocol. 7 | 8 | Inputs (JSON string): 9 | - amount: number, amount to trade (required) 10 | - symbol: string, token symbol (required) 11 | - action: "long" | "short", trade direction (required) 12 | - type: "market" | "limit", order type (required) 13 | - price: number, required for limit orders`; 14 | 15 | constructor(private solanaKit: SolanaAgentKit) { 16 | super(); 17 | } 18 | 19 | protected async _call(input: string): Promise { 20 | try { 21 | const parsedInput = JSON.parse(input); 22 | const signature = await this.solanaKit.tradeUsingDriftPerpAccount( 23 | parsedInput.amount, 24 | parsedInput.symbol, 25 | parsedInput.action, 26 | parsedInput.type, 27 | parsedInput.price, 28 | ); 29 | 30 | return JSON.stringify({ 31 | status: "success", 32 | signature, 33 | }); 34 | } catch (error: any) { 35 | return JSON.stringify({ 36 | status: "error", 37 | message: error.message, 38 | code: error.code || "TRADE_PERP_ACCOUNT_ERROR", 39 | }); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/langchain/drift/unstake_from_insurance_fund.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import type { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaUnstakeFromDriftInsuranceFundTool extends Tool { 5 | name = "unstake_from_drift_insurance_fund"; 6 | description = `Unstake tokens from Drift Insurance Fund after request period has elapsed. 7 | 8 | Inputs (JSON string): 9 | - symbol: string, token symbol (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const tx = await this.solanaKit.unstakeFromDriftInsuranceFund(input); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: `Unstaked ${input} from the Drift Insurance Fund`, 22 | signature: tx, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/drift/update_drift_vault_delegate.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaUpdateDriftVaultDelegateTool extends Tool { 5 | name = "update_drift_vault_delegate"; 6 | description = `Update the delegate of a drift vault. 7 | 8 | Inputs (JSON string): 9 | - vaultAddress: string, address of the vault (required) 10 | - newDelegate: string, address of the new delegate (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | const tx = await this.solanaKit.updateDriftVaultDelegate( 20 | parsedInput.vaultAddress, 21 | parsedInput.newDelegate, 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "Vault delegate updated successfully", 27 | signature: tx, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "UPDATE_DRIFT_VAULT_DELEGATE_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/drift/vault_info.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDriftVaultInfoTool extends Tool { 5 | name = "drift_vault_info"; 6 | description = `Get information about a drift vault. 7 | 8 | Inputs (JSON string): 9 | - vaultNameOrAddress: string, name or address of the vault (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const vaultInfo = await this.solanaKit.getDriftVaultInfo(input); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: "Vault info retrieved successfully", 22 | data: vaultInfo, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "DRIFT_VAULT_INFO_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/drift/withdraw_from_account.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaWithdrawFromDriftAccountTool extends Tool { 5 | name = "withdraw_from_drift_account"; 6 | description = `Withdraw or borrow funds from your drift account. 7 | 8 | Inputs (JSON string): 9 | - amount: number, amount to withdraw (required) 10 | - symbol: string, token symbol (required) 11 | - isBorrow: boolean, whether to borrow funds instead of withdrawing (optional, default: false)`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const parsedInput = JSON.parse(input); 20 | const tx = await this.solanaKit.withdrawFromDriftAccount( 21 | parsedInput.amount, 22 | parsedInput.symbol, 23 | parsedInput.isBorrow, 24 | ); 25 | 26 | return JSON.stringify({ 27 | status: "success", 28 | message: "Funds withdrawn successfully", 29 | signature: tx, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "WITHDRAW_FROM_DRIFT_ACCOUNT_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/drift/withdraw_from_vault.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaWithdrawFromDriftVaultTool extends Tool { 5 | name = "withdraw_from_drift_vault"; 6 | description = `Withdraw funds from a vault given the redemption time has elapsed. 7 | 8 | Inputs (JSON string): 9 | - vaultAddress: string, vault address (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const tx = await this.solanaKit.withdrawFromDriftVault(input); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: "Withdrawal successful", 22 | signature: tx, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "WITHDRAW_FROM_DRIFT_VAULT_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/flash/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./flash_open"; 2 | export * from "./flash_close"; 3 | -------------------------------------------------------------------------------- /src/langchain/gibwork/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_task"; 2 | -------------------------------------------------------------------------------- /src/langchain/helius/delete_webhook.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDeleteHeliusWebhookTool extends Tool { 5 | name = "delete_helius_webhook"; 6 | description = `Deletes a Helius Webhook by its ID. 7 | Inputs (input is a JSON string): 8 | webhookID: string, e.g. "1ed4244d-a591-4854-ac31-cc28d40b8255"`; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | protected async _call(input: string): Promise { 15 | try { 16 | const parsedInput = JSON.parse(input); 17 | 18 | const webhookID = parsedInput.webhookID; 19 | if (!webhookID || typeof webhookID !== "string") { 20 | throw new Error( 21 | 'Invalid input. Expected a "webhookID" property in the JSON.', 22 | ); 23 | } 24 | const result = await this.solanaKit.deleteWebhook(webhookID); 25 | 26 | return JSON.stringify({ 27 | status: "success", 28 | message: "Helius Webhook deleted successfully", 29 | data: result, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "UNKNOWN_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/helius/get_all_assets.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | 5 | export class SolanaGetAllAssetsByOwner extends Tool { 6 | name = "solana_get_all_assets_by_owner"; 7 | description = `Get all assets owned by a specific wallet address. 8 | Inputs: 9 | - owner: string, the wallet address of the owner, e.g., "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required) 10 | - limit: number, the maximum number of assets to retrieve (optional)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const { owner, limit } = JSON.parse(input); 19 | const ownerPubkey = new PublicKey(owner); 20 | 21 | const assets = await this.solanaKit.getAllAssetsbyOwner( 22 | ownerPubkey, 23 | limit, 24 | ); 25 | return JSON.stringify({ 26 | status: "success", 27 | message: "Assets retrieved successfully", 28 | assets: assets, 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "UNKNOWN_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/helius/get_webhook.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaGetHeliusWebhookTool extends Tool { 5 | name = "get_helius_webhook"; 6 | description = `Retrieves a Helius Webhook by its ID. 7 | Inputs (input is a JSON string): 8 | webhookID: string, e.g. "1ed4244d-a591-4854-ac31-cc28d40b8255"`; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | protected async _call(input: string): Promise { 15 | try { 16 | const parsedInput = JSON.parse(input); 17 | 18 | const webhookID = parsedInput.webhookID; 19 | if (!webhookID || typeof webhookID !== "string") { 20 | throw new Error( 21 | 'Invalid input. Expected a "webhookID" property in the JSON.', 22 | ); 23 | } 24 | 25 | const result = await this.solanaKit.getWebhook(webhookID); 26 | return JSON.stringify({ 27 | status: "success", 28 | message: "Helius Webhook retrieved successfully", 29 | wallet: result.wallet, 30 | webhookURL: result.webhookURL, 31 | transactionTypes: result.transactionTypes, 32 | accountAddresses: result.accountAddresses, 33 | webhookType: result.webhookType, 34 | }); 35 | } catch (error: any) { 36 | return JSON.stringify({ 37 | status: "error", 38 | message: error.message, 39 | code: error.code || "UNKNOWN_ERROR", 40 | }); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/langchain/helius/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_webhook"; 2 | export * from "./delete_webhook"; 3 | export * from "./get_all_assets"; 4 | export * from "./get_webhook"; 5 | export * from "./parse_transaction"; 6 | export * from "./send_transaction_priority"; 7 | -------------------------------------------------------------------------------- /src/langchain/helius/parse_transaction.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaParseTransactionHeliusTool extends Tool { 5 | name = "solana_parse_transaction_helius"; 6 | description = `Parse a Solana transaction using Helius API. 7 | Inputs: 8 | - transactionId: string, the ID of the transaction to parse, e.g., "5h3k...9d2k" (required).`; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | protected async _call(input: string): Promise { 15 | try { 16 | const transactionId = input.trim(); 17 | const parsedTransaction = 18 | await this.solanaKit.heliusParseTransactions(transactionId); 19 | return JSON.stringify({ 20 | status: "success", 21 | message: "transaction parsed successfully", 22 | transaction: parsedTransaction, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "NOt able to Parse transaction", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/jupiter/fetch_price.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | /** 5 | * Tool to fetch the price of a token in USDC 6 | */ 7 | export class SolanaFetchPriceTool extends Tool { 8 | name = "solana_fetch_price"; 9 | description = `Fetch the price of a given token in USDC. 10 | 11 | Inputs: 12 | - tokenId: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"`; 13 | 14 | constructor(private solanaKit: SolanaAgentKit) { 15 | super(); 16 | } 17 | 18 | async _call(input: string): Promise { 19 | try { 20 | const price = await this.solanaKit.fetchTokenPrice(input.trim()); 21 | return JSON.stringify({ 22 | status: "success", 23 | tokenId: input.trim(), 24 | priceInUSDC: price, 25 | }); 26 | } catch (error: any) { 27 | return JSON.stringify({ 28 | status: "error", 29 | message: error.message, 30 | code: error.code || "UNKNOWN_ERROR", 31 | }); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/langchain/jupiter/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./fetch_price"; 2 | export * from "./token_data"; 3 | export * from "./trade"; 4 | export * from "./stake"; 5 | -------------------------------------------------------------------------------- /src/langchain/jupiter/stake.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaStakeTool extends Tool { 5 | name = "solana_stake"; 6 | description = `This tool can be used to stake your SOL (Solana), also called as SOL staking or liquid staking. 7 | 8 | Inputs ( input is a JSON string ): 9 | amount: number, eg 1 or 0.01 (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const parsedInput = JSON.parse(input) || Number(input); 18 | 19 | const tx = await this.solanaKit.stake(parsedInput.amount); 20 | 21 | return JSON.stringify({ 22 | status: "success", 23 | message: "Staked successfully", 24 | transaction: tx, 25 | amount: parsedInput.amount, 26 | }); 27 | } catch (error: any) { 28 | return JSON.stringify({ 29 | status: "error", 30 | message: error.message, 31 | code: error.code || "UNKNOWN_ERROR", 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/jupiter/token_data.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaTokenDataTool extends Tool { 5 | name = "solana_token_data"; 6 | description = `Get the token data for a given token mint address 7 | 8 | Inputs: mintAddress is required. 9 | mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const parsedInput = input.trim(); 18 | 19 | const tokenData = await this.solanaKit.getTokenDataByAddress(parsedInput); 20 | 21 | return JSON.stringify({ 22 | status: "success", 23 | tokenData, 24 | }); 25 | } catch (error: any) { 26 | return JSON.stringify({ 27 | status: "error", 28 | message: error.message, 29 | code: error.code || "UNKNOWN_ERROR", 30 | }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/langchain/lightprotocol/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./compressed_airdrop"; 2 | -------------------------------------------------------------------------------- /src/langchain/lulo/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./lend_asset"; 2 | export * from "./lulo_lend"; 3 | export * from "./lulo_withdraw"; 4 | -------------------------------------------------------------------------------- /src/langchain/lulo/lend_asset.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaLendAssetTool extends Tool { 5 | name = "solana_lend_asset"; 6 | description = `Lend idle USDC for yield using Lulo. ( only USDC is supported ) 7 | 8 | Inputs (input is a json string): 9 | amount: number, eg 1, 0.01 (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | async _call(input: string): Promise { 16 | try { 17 | const amount = JSON.parse(input).amount || input; 18 | 19 | const tx = await this.solanaKit.lendAssets(amount); 20 | 21 | return JSON.stringify({ 22 | status: "success", 23 | message: "Asset lent successfully", 24 | transaction: tx, 25 | amount, 26 | }); 27 | } catch (error: any) { 28 | return JSON.stringify({ 29 | status: "error", 30 | message: error.message, 31 | code: error.code || "UNKNOWN_ERROR", 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/lulo/lulo_lend.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaLuloLendTool extends Tool { 5 | name = "solana_lulo_lend"; 6 | description = `Lend token for yield using Lulo. (support USDC/PYUSD/USDS/USDT/SOL/jitoSOL/bSOL/mSOL/BONK/JUP) 7 | Inputs: 8 | mintAddress: string, eg "So11111111111111111111111111111111111111112" (required) 9 | amount: number, eg 1, 0.01 (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | async _call(input: string): Promise { 16 | try { 17 | const parsedInput = JSON.parse(input); 18 | const mintAddress = parsedInput.mintAddress; 19 | const amount = parsedInput.amount; 20 | 21 | const tx = await this.solanaKit.luloLend(mintAddress, amount); 22 | 23 | return JSON.stringify({ 24 | status: "success", 25 | message: "Asset lent successfully", 26 | transaction: tx, 27 | amount, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "UNKNOWN_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/lulo/lulo_withdraw.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaLuloWithdrawTool extends Tool { 5 | name = "solana_lulo_withdraw"; 6 | description = `Withdraw token USDC using Lulo. (support USDC/PYUSD/USDS/USDT/SOL/jitoSOL/bSOL/mSOL/BONK/JUP) 7 | Inputs (input is a json string): 8 | mintAddress: string, eg "So11111111111111111111111111111111111111112" (required) 9 | amount: number, eg 1, 0.01 (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | async _call(input: string): Promise { 16 | try { 17 | const parsedInput = JSON.parse(input); 18 | const mintAddress = parsedInput.mintAddress; 19 | const amount = parsedInput.amount; 20 | 21 | const tx = await this.solanaKit.luloWithdraw(mintAddress, amount); 22 | 23 | return JSON.stringify({ 24 | status: "success", 25 | message: "Asset withdraw successfully", 26 | transaction: tx, 27 | amount, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "UNKNOWN_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/manifest/cancel_orders.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaCancelAllOrdersTool extends Tool { 6 | name = "solana_cancel_all_orders"; 7 | description = `This tool can be used to cancel all orders from a Manifest market. 8 | 9 | Input ( input is a JSON string ): 10 | marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const marketId = new PublicKey(input.trim()); 19 | const tx = await this.solanaKit.cancelAllOrders(marketId); 20 | 21 | return JSON.stringify({ 22 | status: "success", 23 | message: "Cancel orders successfully", 24 | transaction: tx, 25 | marketId, 26 | }); 27 | } catch (error: any) { 28 | return JSON.stringify({ 29 | status: "error", 30 | message: error.message, 31 | code: error.code || "UNKNOWN_ERROR", 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/manifest/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./manifest_market"; 2 | export * from "./batch_order"; 3 | export * from "./cancel_orders"; 4 | export * from "./limit_order"; 5 | export * from "./withdraw"; 6 | -------------------------------------------------------------------------------- /src/langchain/manifest/manifest_market.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaManifestCreateMarket extends Tool { 6 | name = "solana_manifest_create_market"; 7 | description = `Manifest market 8 | 9 | Inputs (input is a json string): 10 | baseMint: string (required) 11 | quoteMint: string (required) 12 | `; 13 | 14 | constructor(private solanaKit: SolanaAgentKit) { 15 | super(); 16 | } 17 | 18 | async _call(input: string): Promise { 19 | try { 20 | const inputFormat = JSON.parse(input); 21 | 22 | const tx = await this.solanaKit.manifestCreateMarket( 23 | new PublicKey(inputFormat.baseMint), 24 | new PublicKey(inputFormat.quoteMint), 25 | ); 26 | 27 | return JSON.stringify({ 28 | status: "success", 29 | message: "Create manifest market successfully", 30 | transaction: tx[0], 31 | marketId: tx[1], 32 | }); 33 | } catch (error: any) { 34 | return JSON.stringify({ 35 | status: "error", 36 | message: error.message, 37 | code: error.code || "UNKNOWN_ERROR", 38 | }); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/langchain/manifest/withdraw.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaWithdrawAllTool extends Tool { 6 | name = "solana_withdraw_all"; 7 | description = `This tool can be used to withdraw all funds from a Manifest market. 8 | 9 | Input ( input is a JSON string ): 10 | marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const marketId = new PublicKey(input.trim()); 19 | const tx = await this.solanaKit.withdrawAll(marketId); 20 | 21 | return JSON.stringify({ 22 | status: "success", 23 | message: "Withdrew successfully", 24 | transaction: tx, 25 | marketId, 26 | }); 27 | } catch (error: any) { 28 | return JSON.stringify({ 29 | status: "error", 30 | message: error.message, 31 | code: error.code || "UNKNOWN_ERROR", 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/metaplex/deploy_collection.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDeployCollectionTool extends Tool { 5 | name = "solana_deploy_collection"; 6 | description = `Deploy a new NFT collection on Solana blockchain. 7 | 8 | Inputs (input is a JSON string): 9 | name: string, eg "My Collection" (required) 10 | uri: string, eg "https://example.com/collection.json" (required) 11 | royaltyBasisPoints?: number, eg 500 for 5% (optional)`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const parsedInput = JSON.parse(input); 20 | 21 | const result = await this.solanaKit.deployCollection(parsedInput); 22 | 23 | return JSON.stringify({ 24 | status: "success", 25 | message: "Collection deployed successfully", 26 | collectionAddress: result.collectionAddress.toString(), 27 | name: parsedInput.name, 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "UNKNOWN_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/metaplex/deploy_token.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaDeployTokenTool extends Tool { 5 | name = "solana_deploy_token"; 6 | description = `Deploy a new token on Solana blockchain. 7 | 8 | Inputs (input is a JSON string): 9 | name: string, eg "My Token" (required) 10 | uri: string, eg "https://example.com/token.json" (required) 11 | symbol: string, eg "MTK" (required) 12 | decimals?: number, eg 9 (optional, defaults to 9) 13 | initialSupply?: number, eg 1000000 (optional)`; 14 | 15 | constructor(private solanaKit: SolanaAgentKit) { 16 | super(); 17 | } 18 | 19 | protected async _call(input: string): Promise { 20 | try { 21 | const parsedInput = JSON.parse(input); 22 | 23 | const result = await this.solanaKit.deployToken( 24 | parsedInput.name, 25 | parsedInput.uri, 26 | parsedInput.symbol, 27 | parsedInput.decimals, 28 | parsedInput.initialSupply, 29 | ); 30 | 31 | return JSON.stringify({ 32 | status: "success", 33 | message: "Token deployed successfully", 34 | mintAddress: result.mint.toString(), 35 | decimals: parsedInput.decimals || 9, 36 | }); 37 | } catch (error: any) { 38 | return JSON.stringify({ 39 | status: "error", 40 | message: error.message, 41 | code: error.code || "UNKNOWN_ERROR", 42 | }); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/langchain/metaplex/get_asset.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaGetAssetTool extends Tool { 5 | name = "solana_get_asset"; 6 | description = `Fetch asset details for a given asset ID using the Metaplex DAS API. 7 | 8 | Inputs (input is a string): 9 | eg "8TrvJBRa6Pzb9BDadqroHhWTHxaxK8Ws8r91oZ2jxaVV" (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const result = await this.solanaKit.getAsset(input); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: "Asset retrieved successfully", 22 | result, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "UNKNOWN_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/metaplex/get_assets_by_authority.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaGetAssetsByAuthorityTool extends Tool { 5 | name = "solana_get_assets_by_authority"; 6 | description = `Fetch a list of assets by a specific authority address using the Metaplex DAS API. 7 | 8 | Inputs (input is a JSON string): 9 | authority: string, eg "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv" (required) 10 | sortBy: { sortBy: "created" | "updated" | "recentAction" | "none", sortDirection: "asc" | "desc" } (optional) 11 | limit: number (optional) 12 | page: number (optional) 13 | before: string (optional) 14 | after: string (optional)`; 15 | 16 | constructor(private solanaKit: SolanaAgentKit) { 17 | super(); 18 | } 19 | 20 | protected async _call(input: string): Promise { 21 | try { 22 | const parsedInput = JSON.parse(input); 23 | 24 | const result = await this.solanaKit.getAssetsByAuthority(parsedInput); 25 | 26 | return JSON.stringify({ 27 | status: "success", 28 | message: "Assets retrieved successfully", 29 | result, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "UNKNOWN_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/metaplex/get_assets_by_creator.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaGetAssetsByCreatorTool extends Tool { 5 | name = "solana_get_assets_by_creator"; 6 | description = `Fetch a list of assets created by a specific address using the Metaplex DAS API. 7 | 8 | Inputs (input is a JSON string): 9 | creator: string, eg "D3XrkNZz6wx6cofot7Zohsf2KSsu2ArngNk8VqU9cTY3" (required) 10 | onlyVerified: boolean (optional) 11 | sortBy: { sortBy: "created" | "updated" | "recentAction" | "none", sortDirection: "asc" | "desc" } (optional) 12 | limit: number (optional) 13 | page: number (optional) 14 | before: string (optional) 15 | after: string (optional)`; 16 | 17 | constructor(private solanaKit: SolanaAgentKit) { 18 | super(); 19 | } 20 | 21 | protected async _call(input: string): Promise { 22 | try { 23 | const parsedInput = JSON.parse(input); 24 | 25 | const result = await this.solanaKit.getAssetsByCreator(parsedInput); 26 | 27 | return JSON.stringify({ 28 | status: "success", 29 | message: "Assets retrieved successfully", 30 | result, 31 | }); 32 | } catch (error: any) { 33 | return JSON.stringify({ 34 | status: "error", 35 | message: error.message, 36 | code: error.code || "UNKNOWN_ERROR", 37 | }); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/langchain/metaplex/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./deploy_collection"; 2 | export * from "./mint_nft"; 3 | export * from "./deploy_token"; 4 | export * from "./get_asset"; 5 | export * from "./get_assets_by_authority"; 6 | export * from "./get_assets_by_creator"; 7 | -------------------------------------------------------------------------------- /src/langchain/meteora/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./meteora_dlmm_pool"; 2 | export * from "./meteora_dynamic_pool"; 3 | -------------------------------------------------------------------------------- /src/langchain/openbook/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./openbook_market"; 2 | -------------------------------------------------------------------------------- /src/langchain/openbook/openbook_market.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaOpenbookCreateMarket extends Tool { 6 | name = "solana_openbook_create_market"; 7 | description = `Openbook marketId, required for ammv4 8 | 9 | Inputs (input is a json string): 10 | baseMint: string (required) 11 | quoteMint: string (required) 12 | lotSize: number (required) 13 | tickSize: number (required) 14 | `; 15 | 16 | constructor(private solanaKit: SolanaAgentKit) { 17 | super(); 18 | } 19 | 20 | async _call(input: string): Promise { 21 | try { 22 | const inputFormat = JSON.parse(input); 23 | 24 | const tx = await this.solanaKit.openbookCreateMarket( 25 | new PublicKey(inputFormat.baseMint), 26 | new PublicKey(inputFormat.quoteMint), 27 | 28 | inputFormat.lotSize, 29 | inputFormat.tickSize, 30 | ); 31 | 32 | return JSON.stringify({ 33 | status: "success", 34 | message: "Openbook market created successfully", 35 | transaction: tx, 36 | }); 37 | } catch (error: any) { 38 | return JSON.stringify({ 39 | status: "error", 40 | message: error.message, 41 | code: error.code || "UNKNOWN_ERROR", 42 | }); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/langchain/orca/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./orca_clmm"; 2 | export * from "./orca_single_sided_pool"; 3 | export * from "./orca_position"; 4 | export * from "./orca_fetch_positions"; 5 | export * from "./orca_centered_position"; 6 | export * from "./orca_single_sided_position"; 7 | -------------------------------------------------------------------------------- /src/langchain/orca/orca_fetch_positions.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaOrcaFetchPositions extends Tool { 5 | name = "orca_fetch_positions"; 6 | description = `Fetch all the liquidity positions in an Orca Whirlpool by owner. Returns an object with positiont mint addresses as keys and position status details as values.`; 7 | 8 | constructor(private solanaKit: SolanaAgentKit) { 9 | super(); 10 | } 11 | 12 | async _call(): Promise { 13 | try { 14 | const txId = await this.solanaKit.orcaFetchPositions(); 15 | 16 | return JSON.stringify({ 17 | status: "success", 18 | message: "Liquidity positions fetched.", 19 | transaction: txId, 20 | }); 21 | } catch (error: any) { 22 | return JSON.stringify({ 23 | status: "error", 24 | message: error.message, 25 | code: error.code || "UNKNOWN_ERROR", 26 | }); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/langchain/orca/orca_position.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaClosePosition extends Tool { 6 | name = "orca_close_position"; 7 | description = `Closes an existing liquidity position in an Orca Whirlpool. This function fetches the position 8 | details using the provided mint address and closes the position with a 1% slippage. 9 | 10 | Inputs (JSON string): 11 | - positionMintAddress: string, the address of the position mint that represents the liquidity position.`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | async _call(input: string): Promise { 18 | try { 19 | const inputFormat = JSON.parse(input); 20 | const positionMintAddress = new PublicKey( 21 | inputFormat.positionMintAddress, 22 | ); 23 | 24 | const txId = await this.solanaKit.orcaClosePosition(positionMintAddress); 25 | 26 | return JSON.stringify({ 27 | status: "success", 28 | message: "Liquidity position closed successfully.", 29 | transaction: txId, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "UNKNOWN_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/pumpfun/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./launch_pumpfun_token"; 2 | -------------------------------------------------------------------------------- /src/langchain/pyth/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./pyth_price"; 2 | -------------------------------------------------------------------------------- /src/langchain/pyth/pyth_price.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PythFetchPriceResponse } from "../../index"; 4 | 5 | export class SolanaPythFetchPrice extends Tool { 6 | name = "solana_pyth_fetch_price"; 7 | description = `Fetch the price of a given price feed from Pyth's Hermes service 8 | 9 | Inputs: 10 | tokenSymbol: string, e.g., BTC for bitcoin`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | async _call(input: string): Promise { 17 | try { 18 | const priceFeedID = await this.solanaKit.getPythPriceFeedID(input); 19 | const price = await this.solanaKit.getPythPrice(priceFeedID); 20 | 21 | const response: PythFetchPriceResponse = { 22 | status: "success", 23 | tokenSymbol: input, 24 | priceFeedID, 25 | price, 26 | }; 27 | 28 | return JSON.stringify(response); 29 | } catch (error: any) { 30 | const response: PythFetchPriceResponse = { 31 | status: "error", 32 | tokenSymbol: input, 33 | message: error.message, 34 | code: error.code || "UNKNOWN_ERROR", 35 | }; 36 | return JSON.stringify(response); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/raydium/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./raydium_amm"; 2 | export * from "./raydium_clmm"; 3 | export * from "./raydium_cpmm"; 4 | export * from "./types"; 5 | -------------------------------------------------------------------------------- /src/langchain/raydium/raydium_amm.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { BN } from "@coral-xyz/anchor"; 3 | import { Tool } from "langchain/tools"; 4 | import { SolanaAgentKit } from "../../agent"; 5 | 6 | export class SolanaRaydiumCreateAmmV4 extends Tool { 7 | name = "raydium_create_ammV4"; 8 | description = `Raydium's Legacy AMM that requires an OpenBook marketID 9 | 10 | Inputs (input is a json string): 11 | marketId: string (required) 12 | baseAmount: number(int), eg: 111111 (required) 13 | quoteAmount: number(int), eg: 111111 (required) 14 | startTime: number(seconds), eg: now number or zero (required) 15 | `; 16 | 17 | constructor(private solanaKit: SolanaAgentKit) { 18 | super(); 19 | } 20 | 21 | async _call(input: string): Promise { 22 | try { 23 | const inputFormat = JSON.parse(input); 24 | 25 | const tx = await this.solanaKit.raydiumCreateAmmV4( 26 | new PublicKey(inputFormat.marketId), 27 | new BN(inputFormat.baseAmount), 28 | new BN(inputFormat.quoteAmount), 29 | new BN(inputFormat.startTime), 30 | ); 31 | 32 | return JSON.stringify({ 33 | status: "success", 34 | message: "Raydium amm v4 pool created successfully", 35 | transaction: tx, 36 | }); 37 | } catch (error: any) { 38 | return JSON.stringify({ 39 | status: "error", 40 | message: error.message, 41 | code: error.code || "UNKNOWN_ERROR", 42 | }); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/langchain/raydium/types.ts: -------------------------------------------------------------------------------- 1 | export interface RaydiumAmmV4Input { 2 | marketId: string; 3 | baseAmount: number | string; 4 | quoteAmount: number | string; 5 | startTime: number; 6 | } 7 | 8 | export interface RaydiumClmmInput { 9 | mint1: string; 10 | mint2: string; 11 | configId: string; 12 | initialPrice: number | string; 13 | startTime: number; 14 | } 15 | 16 | export interface RaydiumCpmmInput { 17 | mint1: string; 18 | mint2: string; 19 | configId: string; 20 | mintAAmount: number | string; 21 | mintBAmount: number | string; 22 | startTime: number; 23 | } 24 | -------------------------------------------------------------------------------- /src/langchain/rugcheck/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./token_report_summary"; 2 | export * from "./token_report_detailed"; 3 | -------------------------------------------------------------------------------- /src/langchain/rugcheck/token_report_detailed.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaFetchTokenDetailedReportTool extends Tool { 5 | name = "solana_fetch_token_detailed_report"; 6 | description = `Fetches a detailed report for a specific token from RugCheck. 7 | Inputs: 8 | - mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | protected async _call(input: string): Promise { 15 | try { 16 | const mint = input.trim(); 17 | const detailedReport = 18 | await this.solanaKit.fetchTokenDetailedReport(mint); 19 | 20 | return JSON.stringify({ 21 | status: "success", 22 | message: "Detailed token report fetched successfully", 23 | report: detailedReport, 24 | }); 25 | } catch (error: any) { 26 | return JSON.stringify({ 27 | status: "error", 28 | message: error.message, 29 | code: error.code || "FETCH_TOKEN_DETAILED_REPORT_ERROR", 30 | }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/langchain/rugcheck/token_report_summary.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaFetchTokenReportSummaryTool extends Tool { 5 | name = "solana_fetch_token_report_summary"; 6 | description = `Fetches a summary report for a specific token from RugCheck. 7 | Inputs: 8 | - mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`; 9 | 10 | constructor(private solanaKit: SolanaAgentKit) { 11 | super(); 12 | } 13 | 14 | protected async _call(input: string): Promise { 15 | try { 16 | const mint = input.trim(); 17 | const report = await this.solanaKit.fetchTokenReportSummary(mint); 18 | 19 | return JSON.stringify({ 20 | status: "success", 21 | message: "Token report summary fetched successfully", 22 | report, 23 | }); 24 | } catch (error: any) { 25 | return JSON.stringify({ 26 | status: "error", 27 | message: error.message, 28 | code: error.code || "FETCH_TOKEN_REPORT_SUMMARY_ERROR", 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/langchain/sendarcade/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./rock_paper_scissors"; 2 | -------------------------------------------------------------------------------- /src/langchain/sns/get_domain.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaGetDomainTool extends Tool { 6 | name = "solana_get_domain"; 7 | description = `Retrieve the .sol domain associated for a given account address. 8 | 9 | Inputs: 10 | account: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required) 11 | `; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const account = new PublicKey(input.trim()); 20 | const domain = await this.solanaKit.getPrimaryDomain(account); 21 | 22 | return JSON.stringify({ 23 | status: "success", 24 | message: "Primary domain retrieved successfully", 25 | domain, 26 | }); 27 | } catch (error: any) { 28 | return JSON.stringify({ 29 | status: "error", 30 | message: error.message, 31 | code: error.code || "UNKNOWN_ERROR", 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/sns/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./register_domain"; 2 | export * from "./resolve_domain"; 3 | export * from "./get_domain"; 4 | export * from "./main_domain"; 5 | -------------------------------------------------------------------------------- /src/langchain/sns/main_domain.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaGetMainDomain extends Tool { 6 | name = "solana_get_main_domain"; 7 | description = `Get the main/favorite domain for a given wallet address. 8 | 9 | Inputs: 10 | owner: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | async _call(input: string): Promise { 17 | try { 18 | const ownerPubkey = new PublicKey(input.trim()); 19 | const mainDomain = 20 | await this.solanaKit.getMainAllDomainsDomain(ownerPubkey); 21 | 22 | return JSON.stringify({ 23 | status: "success", 24 | message: "Main domain fetched successfully", 25 | domain: mainDomain, 26 | }); 27 | } catch (error: any) { 28 | return JSON.stringify({ 29 | status: "error", 30 | message: error.message, 31 | code: error.code || "FETCH_MAIN_DOMAIN_ERROR", 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/sns/resolve_domain.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaResolveDomainTool extends Tool { 5 | name = "solana_resolve_domain"; 6 | description = `Resolve ONLY .sol domain names to a Solana PublicKey. 7 | This tool is exclusively for .sol domains. 8 | DO NOT use this for other domain types like .blink, .bonk, etc. 9 | 10 | Inputs: 11 | domain: string, eg "pumpfun.sol" (required) 12 | `; 13 | 14 | constructor(private solanaKit: SolanaAgentKit) { 15 | super(); 16 | } 17 | 18 | protected async _call(input: string): Promise { 19 | try { 20 | const domain = input.trim(); 21 | const publicKey = await this.solanaKit.resolveSolDomain(domain); 22 | 23 | return JSON.stringify({ 24 | status: "success", 25 | message: "Domain resolved successfully", 26 | publicKey: publicKey.toBase58(), 27 | }); 28 | } catch (error: any) { 29 | return JSON.stringify({ 30 | status: "error", 31 | message: error.message, 32 | code: error.code || "UNKNOWN_ERROR", 33 | }); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/langchain/solana/balance.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaBalanceTool extends Tool { 6 | name = "solana_balance"; 7 | description = `Get the balance of a Solana wallet or token account. 8 | 9 | If you want to get the balance of your wallet, you don't need to provide the tokenAddress. 10 | If no tokenAddress is provided, the balance will be in SOL. 11 | 12 | Inputs ( input is a JSON string ): 13 | tokenAddress: string, eg "So11111111111111111111111111111111111111112" (optional)`; 14 | 15 | constructor(private solanaKit: SolanaAgentKit) { 16 | super(); 17 | } 18 | 19 | protected async _call(input: string): Promise { 20 | try { 21 | const tokenAddress = input ? new PublicKey(input) : undefined; 22 | const balance = await this.solanaKit.getBalance(tokenAddress); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | balance, 27 | token: input || "SOL", 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "UNKNOWN_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/solana/close_empty_accounts.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaCloseEmptyTokenAccounts extends Tool { 5 | name = "close_empty_token_accounts"; 6 | description = `Close all empty spl-token accounts and reclaim the rent`; 7 | 8 | constructor(private solanaKit: SolanaAgentKit) { 9 | super(); 10 | } 11 | 12 | protected async _call(): Promise { 13 | try { 14 | const { signature, size } = 15 | await this.solanaKit.closeEmptyTokenAccounts(); 16 | 17 | return JSON.stringify({ 18 | status: "success", 19 | message: `${size} accounts closed successfully. ${size === 48 ? "48 accounts can be closed in a single transaction try again to close more accounts" : ""}`, 20 | signature, 21 | }); 22 | } catch (error: any) { 23 | return JSON.stringify({ 24 | status: "error", 25 | message: error.message, 26 | code: error.code || "UNKNOWN_ERROR", 27 | }); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/langchain/solana/get_tps.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaTPSCalculatorTool extends Tool { 5 | name = "solana_get_tps"; 6 | description = "Get the current TPS of the Solana network"; 7 | 8 | constructor(private solanaKit: SolanaAgentKit) { 9 | super(); 10 | } 11 | 12 | async _call(_input: string): Promise { 13 | try { 14 | const tps = await this.solanaKit.getTPS(); 15 | return `Solana (mainnet-beta) current transactions per second: ${tps}`; 16 | } catch (error: any) { 17 | return `Error fetching TPS: ${error.message}`; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/langchain/solana/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_tps"; 2 | export * from "./request_funds"; 3 | export * from "./balance"; 4 | export * from "./balance_other"; 5 | export * from "./close_empty_accounts"; 6 | export * from "./transfer"; 7 | -------------------------------------------------------------------------------- /src/langchain/solana/request_funds.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaRequestFundsTool extends Tool { 5 | name = "solana_request_funds"; 6 | description = "Request SOL from Solana faucet (devnet/testnet only)"; 7 | 8 | constructor(private solanaKit: SolanaAgentKit) { 9 | super(); 10 | } 11 | 12 | protected async _call(_input: string): Promise { 13 | try { 14 | await this.solanaKit.requestFaucetFunds(); 15 | 16 | return JSON.stringify({ 17 | status: "success", 18 | message: "Successfully requested faucet funds", 19 | network: this.solanaKit.connection.rpcEndpoint.split("/")[2], 20 | }); 21 | } catch (error: any) { 22 | return JSON.stringify({ 23 | status: "error", 24 | message: error.message, 25 | code: error.code || "UNKNOWN_ERROR", 26 | }); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/langchain/solayer/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./restake"; 2 | -------------------------------------------------------------------------------- /src/langchain/solayer/restake.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaRestakeTool extends Tool { 5 | name = "solana_restake"; 6 | description = `This tool can be used to restake your SOL on Solayer to receive Solayer SOL (sSOL) as a Liquid Staking Token (LST). 7 | 8 | Inputs: 9 | amount: number, eg 1 or 0.01 (required)`; 10 | 11 | constructor(private solanaKit: SolanaAgentKit) { 12 | super(); 13 | } 14 | 15 | protected async _call(input: string): Promise { 16 | try { 17 | const parsedInput = JSON.parse(input) || Number(input); 18 | 19 | const tx = await this.solanaKit.restake(parsedInput.amount); 20 | 21 | return JSON.stringify({ 22 | status: "success", 23 | message: "Staked successfully", 24 | transaction: tx, 25 | amount: parsedInput.amount, 26 | }); 27 | } catch (error: any) { 28 | return JSON.stringify({ 29 | status: "error", 30 | message: error.message, 31 | code: error.code || "UNKNOWN_ERROR", 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/langchain/squads/approve_proposal.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaApproveProposal2by2Multisig extends Tool { 5 | name = "approve_proposal_2by2_multisig"; 6 | description = `Approve a proposal to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. 7 | 8 | If proposalIndex is not provided, the latest index will automatically be fetched and used. 9 | 10 | Inputs (JSON string): 11 | - proposalIndex: number, the index of the proposal (optional).`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const inputFormat = JSON.parse(input); 20 | const proposalIndex = inputFormat.proposalIndex ?? undefined; 21 | 22 | const tx = await this.solanaKit.approveMultisigProposal(proposalIndex); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "Proposal approved successfully", 27 | transaction: tx, 28 | proposalIndex: proposalIndex.toString(), 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "APPROVE_PROPOSAL_2BY2_MULTISIG_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/squads/create_multisig.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | 5 | export class SolanaCreate2by2Multisig extends Tool { 6 | name = "create_2by2_multisig"; 7 | description = `Create a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. 8 | 9 | Note: For one AI agent, only one 2-by-2 multisig can be created as it is pair-wise. 10 | 11 | Inputs (JSON string): 12 | - creator: string, the public key of the creator (required).`; 13 | 14 | constructor(private solanaKit: SolanaAgentKit) { 15 | super(); 16 | } 17 | 18 | protected async _call(input: string): Promise { 19 | try { 20 | const inputFormat = JSON.parse(input); 21 | const creator = new PublicKey(inputFormat.creator); 22 | 23 | const multisig = await this.solanaKit.createSquadsMultisig(creator); 24 | 25 | return JSON.stringify({ 26 | status: "success", 27 | message: "2-by-2 multisig account created successfully", 28 | multisig, 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "CREATE_2BY2_MULTISIG_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/squads/create_proposal.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaCreateProposal2by2Multisig extends Tool { 5 | name = "create_proposal_2by2_multisig"; 6 | description = `Create a proposal to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. 7 | 8 | If transactionIndex is not provided, the latest index will automatically be fetched and used. 9 | 10 | Inputs (JSON string): 11 | - transactionIndex: number, the index of the transaction (optional).`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const inputFormat = JSON.parse(input); 20 | const transactionIndex = inputFormat.transactionIndex ?? undefined; 21 | 22 | const tx = await this.solanaKit.createMultisigProposal(transactionIndex); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "Proposal created successfully", 27 | transaction: tx, 28 | transactionIndex: transactionIndex?.toString(), 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "CREATE_PROPOSAL_2BY2_MULTISIG_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/squads/deposit_to_multisig.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import Decimal from "decimal.js"; 4 | 5 | export class SolanaDepositTo2by2Multisig extends Tool { 6 | name = "deposit_to_2by2_multisig"; 7 | description = `Deposit funds to a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. 8 | 9 | Inputs (JSON string): 10 | - amount: number, the amount to deposit in SOL (required).`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const inputFormat = JSON.parse(input); 19 | const amount = new Decimal(inputFormat.amount); 20 | 21 | const tx = await this.solanaKit.depositToMultisig(amount.toNumber()); 22 | 23 | return JSON.stringify({ 24 | status: "success", 25 | message: "Funds deposited to 2-by-2 multisig account successfully", 26 | transaction: tx, 27 | amount: amount.toString(), 28 | }); 29 | } catch (error: any) { 30 | return JSON.stringify({ 31 | status: "error", 32 | message: error.message, 33 | code: error.code || "DEPOSIT_TO_2BY2_MULTISIG_ERROR", 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/langchain/squads/execute_proposal.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaExecuteProposal2by2Multisig extends Tool { 5 | name = "execute_proposal_2by2_multisig"; 6 | description = `Execute a proposal/transaction to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. 7 | 8 | If proposalIndex is not provided, the latest index will automatically be fetched and used. 9 | 10 | Inputs (JSON string): 11 | - proposalIndex: number, the index of the proposal (optional).`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const inputFormat = JSON.parse(input); 20 | const proposalIndex = inputFormat.proposalIndex ?? undefined; 21 | 22 | const tx = await this.solanaKit.executeMultisigTransaction(proposalIndex); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "Proposal executed successfully", 27 | transaction: tx, 28 | proposalIndex: proposalIndex.toString(), 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "EXECUTE_PROPOSAL_2BY2_MULTISIG_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/squads/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./approve_proposal"; 2 | export * from "./create_multisig"; 3 | export * from "./create_proposal"; 4 | export * from "./deposit_to_multisig"; 5 | export * from "./execute_proposal"; 6 | export * from "./reject_proposal"; 7 | export * from "./transfer_from_multisig"; 8 | -------------------------------------------------------------------------------- /src/langchain/squads/reject_proposal.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | 4 | export class SolanaRejectProposal2by2Multisig extends Tool { 5 | name = "reject_proposal_2by2_multisig"; 6 | description = `Reject a proposal to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. 7 | 8 | If proposalIndex is not provided, the latest index will automatically be fetched and used. 9 | 10 | Inputs (JSON string): 11 | - proposalIndex: number, the index of the proposal (optional).`; 12 | 13 | constructor(private solanaKit: SolanaAgentKit) { 14 | super(); 15 | } 16 | 17 | protected async _call(input: string): Promise { 18 | try { 19 | const inputFormat = JSON.parse(input); 20 | const proposalIndex = inputFormat.proposalIndex ?? undefined; 21 | 22 | const tx = await this.solanaKit.rejectMultisigProposal(proposalIndex); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "Proposal rejected successfully", 27 | transaction: tx, 28 | proposalIndex: proposalIndex.toString(), 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "REJECT_PROPOSAL_2BY2_MULTISIG_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/tensor/cancel_listing.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | import { Tool } from "langchain/tools"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | export class SolanaCancelNFTListingTool extends Tool { 6 | name = "solana_cancel_nft_listing"; 7 | description = `Cancel an NFT listing on Tensor Trade. 8 | 9 | Inputs (input is a JSON string): 10 | nftMint: string, the mint address of the NFT (required)`; 11 | 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | 16 | protected async _call(input: string): Promise { 17 | try { 18 | const parsedInput = JSON.parse(input); 19 | 20 | const tx = await this.solanaKit.tensorCancelListing( 21 | new PublicKey(parsedInput.nftMint), 22 | ); 23 | 24 | return JSON.stringify({ 25 | status: "success", 26 | message: "NFT listing cancelled successfully", 27 | transaction: tx, 28 | nftMint: parsedInput.nftMint, 29 | }); 30 | } catch (error: any) { 31 | return JSON.stringify({ 32 | status: "error", 33 | message: error.message, 34 | code: error.code || "UNKNOWN_ERROR", 35 | }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/langchain/tensor/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./list_nft"; 2 | export * from "./cancel_listing"; 3 | -------------------------------------------------------------------------------- /src/langchain/tiplink/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./tiplink"; 2 | -------------------------------------------------------------------------------- /src/langchain/voltr/deposit_strategy.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | import { BN } from "bn.js"; 5 | 6 | export class SolanaVoltrDepositStrategy extends Tool { 7 | name = "solana_voltr_deposit_strategy"; 8 | description = `Deposit amount into a strategy for Voltr's vaults 9 | 10 | Inputs (input is a json string): 11 | depositAmount: number (required) 12 | vault: string (required) 13 | strategy: string (required) 14 | `; 15 | constructor(private solanaKit: SolanaAgentKit) { 16 | super(); 17 | } 18 | async _call(input: string): Promise { 19 | try { 20 | const inputFormat = JSON.parse(input); 21 | const tx = await this.solanaKit.voltrDepositStrategy( 22 | new BN(inputFormat.depositAmount), 23 | new PublicKey(inputFormat.vault), 24 | new PublicKey(inputFormat.strategy), 25 | ); 26 | return JSON.stringify({ 27 | status: "success", 28 | message: `Deposited ${inputFormat.depositAmount} into strategy ${inputFormat.strategy} of vault ${inputFormat.vault} successfully`, 29 | transaction: tx, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "UNKNOWN_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/langchain/voltr/get_position_values.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | 5 | export class SolanaVoltrGetPositionValues extends Tool { 6 | name = "solana_voltr_get_position_values"; 7 | description = `Get the total asset value and current value for each strategy of a given Voltr vault 8 | 9 | Inputs: 10 | vault: string (required) 11 | `; 12 | constructor(private solanaKit: SolanaAgentKit) { 13 | super(); 14 | } 15 | async _call(input: string): Promise { 16 | return this.solanaKit.voltrGetPositionValues(new PublicKey(input)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/langchain/voltr/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./deposit_strategy"; 2 | export * from "./withdraw_strategy"; 3 | export * from "./get_position_values"; 4 | -------------------------------------------------------------------------------- /src/langchain/voltr/withdraw_strategy.ts: -------------------------------------------------------------------------------- 1 | import { Tool } from "langchain/tools"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | import { BN } from "bn.js"; 5 | 6 | export class SolanaVoltrWithdrawStrategy extends Tool { 7 | name = "solana_voltr_withdraw_strategy"; 8 | description = `Withdraw amount from a strategy for Voltr's vaults 9 | 10 | Inputs (input is a json string): 11 | withdrawAmount: number (required) 12 | vault: string (required) 13 | strategy: string (required) 14 | `; 15 | constructor(private solanaKit: SolanaAgentKit) { 16 | super(); 17 | } 18 | async _call(input: string): Promise { 19 | try { 20 | const inputFormat = JSON.parse(input); 21 | const tx = await this.solanaKit.voltrWithdrawStrategy( 22 | new BN(inputFormat.withdrawAmount), 23 | new PublicKey(inputFormat.vault), 24 | new PublicKey(inputFormat.strategy), 25 | ); 26 | return JSON.stringify({ 27 | status: "success", 28 | message: `Withdrew ${inputFormat.withdrawAmount} from strategy ${inputFormat.strategy} of vault ${inputFormat.vault} successfully`, 29 | transaction: tx, 30 | }); 31 | } catch (error: any) { 32 | return JSON.stringify({ 33 | status: "error", 34 | message: error.message, 35 | code: error.code || "UNKNOWN_ERROR", 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/tools/3land/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_3land_collectible"; 2 | -------------------------------------------------------------------------------- /src/tools/adrena/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./adrena_perp_trading"; 2 | -------------------------------------------------------------------------------- /src/tools/agent/create_image.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../index"; 2 | import OpenAI from "openai"; 3 | 4 | /** 5 | * Generate an image using OpenAI's DALL-E 6 | * @param agent SolanaAgentKit instance 7 | * @param prompt Text description of the image to generate 8 | * @param size Image size ('256x256', '512x512', or '1024x1024') (default: '1024x1024') 9 | * @param n Number of images to generate (default: 1) 10 | * @returns Object containing the generated image URLs 11 | */ 12 | export async function create_image( 13 | agent: SolanaAgentKit, 14 | prompt: string, 15 | size: "256x256" | "512x512" | "1024x1024" = "1024x1024", 16 | n: number = 1, 17 | ) { 18 | try { 19 | if (!agent.config.OPENAI_API_KEY) { 20 | throw new Error("OpenAI API key not found in agent configuration"); 21 | } 22 | 23 | const openai = new OpenAI({ 24 | apiKey: agent.config.OPENAI_API_KEY, 25 | }); 26 | 27 | const response = await openai.images.generate({ 28 | prompt, 29 | n, 30 | size, 31 | }); 32 | 33 | return { 34 | images: response.data.map((img: any) => img.url), 35 | }; 36 | } catch (error: any) { 37 | throw new Error(`Image generation failed: ${error.message}`); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/tools/agent/get_wallet_address.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../agent"; 2 | 3 | /** 4 | * Get the agents wallet address 5 | * @param agent - SolanaAgentKit instance 6 | * @returns string 7 | */ 8 | export function get_wallet_address(agent: SolanaAgentKit) { 9 | return agent.wallet_address.toBase58(); 10 | } 11 | -------------------------------------------------------------------------------- /src/tools/agent/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_image"; 2 | export * from "./get_wallet_address"; 3 | export * from "./get_info"; 4 | -------------------------------------------------------------------------------- /src/tools/alldomains/get_all_domains_tlds.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../index"; 2 | import { getAllTld } from "@onsol/tldparser"; 3 | 4 | /** 5 | * Get all active top-level domains (TLDs) in the AllDomains Name Service 6 | * @param agent SolanaAgentKit instance 7 | * @returns Array of active TLD strings 8 | */ 9 | export async function getAllDomainsTLDs( 10 | agent: SolanaAgentKit, 11 | ): Promise { 12 | try { 13 | const tlds = await getAllTld(agent.connection); 14 | return tlds.map((tld) => String(tld.tld)); 15 | } catch (error: any) { 16 | throw new Error(`Failed to fetch TLDs: ${error.message}`); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/tools/alldomains/get_owned_all_domains.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../agent"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | import { TldParser } from "@onsol/tldparser"; 4 | 5 | /** 6 | * Get all domains owned domains for a specific TLD for the agent's wallet 7 | * @param agent SolanaAgentKit instance 8 | * @param owner - PublicKey of the owner 9 | * @returns Promise resolving to an array of owned domains or an empty array if none are found 10 | */ 11 | export async function getOwnedAllDomains( 12 | agent: SolanaAgentKit, 13 | owner: PublicKey, 14 | ): Promise { 15 | try { 16 | const domains = await new TldParser( 17 | agent.connection, 18 | ).getParsedAllUserDomains(owner); 19 | return domains.map((domain) => domain.domain); 20 | } catch (error: any) { 21 | throw new Error(`Failed to fetch owned domains: ${error.message}`); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/tools/alldomains/get_owned_domains_for_tld.ts: -------------------------------------------------------------------------------- 1 | import { TldParser } from "@onsol/tldparser"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | /** 4 | * Get all domains owned by an address for a specific TLD 5 | * @param agent SolanaAgentKit instance 6 | * @param tld Top-level domain (e.g., "sol") 7 | * @returns Promise resolving to an array of owned domain names for the specified TLD or an empty array if none are found 8 | */ 9 | export async function getOwnedDomainsForTLD( 10 | agent: SolanaAgentKit, 11 | tld: string, 12 | ): Promise { 13 | try { 14 | const domains = await new TldParser( 15 | agent.connection, 16 | ).getParsedAllUserDomainsFromTld(agent.wallet_address, tld); 17 | return domains.map((domain) => domain.domain); 18 | } catch (error: any) { 19 | throw new Error(`Failed to fetch domains for TLD: ${error.message}`); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/tools/alldomains/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_all_domains_tlds"; 2 | export * from "./get_owned_all_domains"; 3 | export * from "./get_owned_domains_for_tld"; 4 | export * from "./resolve_domain"; 5 | -------------------------------------------------------------------------------- /src/tools/alldomains/resolve_domain.ts: -------------------------------------------------------------------------------- 1 | import { TldParser } from "@onsol/tldparser"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | 5 | /** 6 | * Resolve all domains for a given agent and domain 7 | * @param agent SolanaAgentKit instance 8 | * @param domain Domain name to resolve 9 | * @returns Promise resolving to the domain or undefined if not found 10 | */ 11 | export async function resolveAllDomains( 12 | agent: SolanaAgentKit, 13 | domain: string, 14 | ): Promise { 15 | try { 16 | const tld = await new TldParser(agent.connection).getOwnerFromDomainTld( 17 | domain, 18 | ); 19 | return tld; 20 | } catch (error: any) { 21 | if ( 22 | error.message.includes( 23 | "Cannot read properties of undefined (reading 'owner')", 24 | ) 25 | ) { 26 | return undefined; 27 | } 28 | throw new Error(`Domain resolution failed: ${error.message}`); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/tools/allora/get_all_topics.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AlloraAPIClient, 3 | AlloraAPIClientConfig, 4 | AlloraTopic, 5 | ChainSlug, 6 | } from "@alloralabs/allora-sdk"; 7 | import { SolanaAgentKit } from "../../agent"; 8 | 9 | export async function getAllTopics( 10 | agent: SolanaAgentKit, 11 | ): Promise { 12 | try { 13 | const chainSlug = 14 | agent.config.ALLORA_NETWORK === "mainnet" 15 | ? ChainSlug.MAINNET 16 | : ChainSlug.TESTNET; 17 | const apiKey = agent.config.ALLORA_API_KEY || "UP-d33e797de5134909854be2b7"; 18 | const apiUrl = agent.config.ALLORA_API_URL || ""; 19 | 20 | const config: AlloraAPIClientConfig = { 21 | apiKey: apiKey, 22 | chainSlug: chainSlug, 23 | baseAPIUrl: apiUrl, 24 | }; 25 | const client = new AlloraAPIClient(config); 26 | 27 | const topics = await client.getAllTopics(); 28 | 29 | return topics; 30 | } catch (error: any) { 31 | throw new Error(`Error fetching topics from Allora: ${error.message}`); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/allora/get_inference_by_topic_id.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AlloraAPIClient, 3 | AlloraAPIClientConfig, 4 | AlloraInference, 5 | ChainSlug, 6 | } from "@alloralabs/allora-sdk"; 7 | import { SolanaAgentKit } from "../../agent"; 8 | 9 | export async function getInferenceByTopicId( 10 | agent: SolanaAgentKit, 11 | topicId: number, 12 | ): Promise { 13 | try { 14 | const chainSlug = 15 | agent.config.ALLORA_NETWORK === "mainnet" 16 | ? ChainSlug.MAINNET 17 | : ChainSlug.TESTNET; 18 | const apiKey = agent.config.ALLORA_API_KEY || "UP-d33e797de5134909854be2b7"; 19 | const apiUrl = agent.config.ALLORA_API_URL || ""; 20 | 21 | const config: AlloraAPIClientConfig = { 22 | apiKey: apiKey, 23 | chainSlug: chainSlug, 24 | baseAPIUrl: apiUrl, 25 | }; 26 | const client = new AlloraAPIClient(config); 27 | const inference = await client.getInferenceByTopicID(topicId); 28 | 29 | return inference; 30 | } catch (error: any) { 31 | throw new Error(`Error fetching inference from Allora: ${error.message}`); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/allora/get_price_inference.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AlloraAPIClient, 3 | PriceInferenceTimeframe, 4 | PriceInferenceToken, 5 | AlloraAPIClientConfig, 6 | ChainSlug, 7 | } from "@alloralabs/allora-sdk"; 8 | import { SolanaAgentKit } from "../../agent"; 9 | 10 | export async function getPriceInference( 11 | agent: SolanaAgentKit, 12 | tokenSymbol: string, 13 | timeframe: string, 14 | ): Promise { 15 | try { 16 | const chainSlug = 17 | agent.config.ALLORA_NETWORK === "mainnet" 18 | ? ChainSlug.MAINNET 19 | : ChainSlug.TESTNET; 20 | const apiKey = agent.config.ALLORA_API_KEY || "UP-d33e797de5134909854be2b7"; 21 | const apiUrl = agent.config.ALLORA_API_URL || ""; 22 | 23 | const config: AlloraAPIClientConfig = { 24 | apiKey: apiKey, 25 | chainSlug: chainSlug, 26 | baseAPIUrl: apiUrl, 27 | }; 28 | const client = new AlloraAPIClient(config); 29 | const inference = await client.getPriceInference( 30 | tokenSymbol as PriceInferenceToken, 31 | timeframe as PriceInferenceTimeframe, 32 | ); 33 | 34 | return inference.inference_data.network_inference_normalized; 35 | } catch (error: any) { 36 | throw new Error( 37 | `Error fetching price inference from Allora: ${error.message}`, 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/tools/allora/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_price_inference"; 2 | export * from "./get_inference_by_topic_id"; 3 | export * from "./get_all_topics"; 4 | -------------------------------------------------------------------------------- /src/tools/dexscreener/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_token_data"; 2 | -------------------------------------------------------------------------------- /src/tools/drift/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./drift"; 2 | export * from "./drift_vault"; 3 | -------------------------------------------------------------------------------- /src/tools/drift/types.ts: -------------------------------------------------------------------------------- 1 | import type { L2OrderBook, MarketType, OraclePriceData } from "@drift-labs/sdk"; 2 | 3 | export type L2WithOracle = L2OrderBook & { oracleData: OraclePriceData }; 4 | 5 | export type RawL2Output = { 6 | marketIndex: number; 7 | marketType: MarketType; 8 | marketName: string; 9 | asks: { 10 | price: string; 11 | size: string; 12 | sources: { 13 | [key: string]: string; 14 | }; 15 | }[]; 16 | bids: { 17 | price: string; 18 | size: string; 19 | sources: { 20 | [key: string]: string; 21 | }; 22 | }[]; 23 | oracleData: { 24 | price: string; 25 | slot: string; 26 | confidence: string; 27 | hasSufficientNumberOfDataPoints: boolean; 28 | twap?: string; 29 | twapConfidence?: string; 30 | maxPrice?: string; 31 | }; 32 | slot?: number; 33 | }; 34 | -------------------------------------------------------------------------------- /src/tools/flash/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./flash_open_trade"; 2 | export * from "./flash_close_trade"; 3 | -------------------------------------------------------------------------------- /src/tools/gibwork/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_gibwork_task"; 2 | -------------------------------------------------------------------------------- /src/tools/helius/helius_transaction_parsing.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../index"; 2 | 3 | /** 4 | * Parse a Solana transaction using the Helius Enhanced Transactions API 5 | * @param agent SolanaAgentKit instance 6 | * @param transactionId The transaction ID to parse 7 | * @returns Parsed transaction data 8 | */ 9 | export async function parseTransaction( 10 | agent: SolanaAgentKit, 11 | transactionId: string, 12 | ): Promise { 13 | try { 14 | const apiKey = agent.config.HELIUS_API_KEY; 15 | if (!apiKey) { 16 | throw new Error("HELIUS_API_KEY not found in environment variables"); 17 | } 18 | 19 | const url = `https://api.helius.xyz/v0/transactions/?api-key=${apiKey}`; 20 | 21 | const response = await fetch(url, { 22 | method: "POST", 23 | headers: { 24 | "Content-Type": "application/json", 25 | }, 26 | body: JSON.stringify({ 27 | transactions: [transactionId], 28 | }), 29 | }); 30 | 31 | if (!response.ok) { 32 | throw new Error( 33 | `Failed to fetch: ${response.status} - ${response.statusText}`, 34 | ); 35 | } 36 | 37 | const data = await response.json(); 38 | 39 | return data; 40 | } catch (error: any) { 41 | console.error("Error parsing transaction: ", error.message); 42 | throw new Error(`Transaction parsing failed: ${error.message}`); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/tools/helius/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_assets_by_owner"; 2 | export * from "./helius_transaction_parsing"; 3 | export * from "./helius_webhooks"; 4 | export * from "./send_transaction_with_priority"; 5 | -------------------------------------------------------------------------------- /src/tools/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./adrena"; 2 | export * from "./sns"; 3 | export * from "./dexscreener"; 4 | export * from "./alldomains"; 5 | export * from "./flash"; 6 | export * from "./gibwork"; 7 | export * from "./jupiter"; 8 | export * from "./lulo"; 9 | export * from "./manifest"; 10 | export * from "./solana"; 11 | export * from "./agent"; 12 | export * from "./metaplex"; 13 | export * from "./openbook"; 14 | export * from "./orca"; 15 | export * from "./pumpfun"; 16 | export * from "./pyth"; 17 | export * from "./raydium"; 18 | export * from "./rugcheck"; 19 | export * from "./drift"; 20 | export * from "./sendarcade"; 21 | export * from "./solayer"; 22 | export * from "./tensor"; 23 | export * from "./3land"; 24 | export * from "./tiplink"; 25 | export * from "./lightprotocol"; 26 | export * from "./squads"; 27 | export * from "./meteora"; 28 | export * from "./helius"; 29 | export * from "./voltr"; 30 | export * from "./allora"; 31 | -------------------------------------------------------------------------------- /src/tools/jupiter/fetch_price.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | 3 | /** 4 | * Fetch the price of a given token quoted in USDC using Jupiter API 5 | * @param tokenId The token mint address 6 | * @returns The price of the token quoted in USDC 7 | */ 8 | export async function fetchPrice(tokenId: PublicKey): Promise { 9 | try { 10 | const response = await fetch(`https://api.jup.ag/price/v2?ids=${tokenId}`); 11 | 12 | if (!response.ok) { 13 | throw new Error(`Failed to fetch price: ${response.statusText}`); 14 | } 15 | 16 | const data = await response.json(); 17 | 18 | const price = data.data[tokenId.toBase58()]?.price; 19 | 20 | if (!price) { 21 | throw new Error("Price data not available for the given token."); 22 | } 23 | 24 | return price; 25 | } catch (error: any) { 26 | throw new Error(`Price fetch failed: ${error.message}`); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/tools/jupiter/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./fetch_price"; 2 | export * from "./stake_with_jup"; 3 | export * from "./trade"; 4 | -------------------------------------------------------------------------------- /src/tools/lightprotocol/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./send_compressed_airdrop"; 2 | -------------------------------------------------------------------------------- /src/tools/lulo/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./lend"; 2 | export * from "./lulo_lend"; 3 | export * from "./lulo_withdraw"; 4 | -------------------------------------------------------------------------------- /src/tools/manifest/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./manifest_trade"; 2 | -------------------------------------------------------------------------------- /src/tools/metaplex/get_asset.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../index"; 2 | import { publicKey } from "@metaplex-foundation/umi"; 3 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 4 | import { 5 | dasApi, 6 | DasApiAsset, 7 | } from "@metaplex-foundation/digital-asset-standard-api"; 8 | 9 | /** 10 | * Fetch asset details using the Metaplex DAS API 11 | * @param agent SolanaAgentKit instance 12 | * @param assetId ID of the asset to fetch 13 | * @returns Asset details 14 | */ 15 | export async function get_asset( 16 | agent: SolanaAgentKit, 17 | assetId: string, 18 | ): Promise { 19 | try { 20 | const endpoint = agent.connection.rpcEndpoint; 21 | const umi = createUmi(endpoint).use(dasApi()); 22 | 23 | return await umi.rpc.getAsset(publicKey(assetId)); 24 | } catch (error: any) { 25 | console.error("Error retrieving asset: ", error.message); 26 | throw new Error(`Asset retrieval failed: ${error.message}`); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/tools/metaplex/get_assets_by_authority.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../agent"; 2 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 3 | import { 4 | dasApi, 5 | GetAssetsByAuthorityRpcInput, 6 | } from "@metaplex-foundation/digital-asset-standard-api"; 7 | 8 | /** 9 | * Fetch assets by authority using the Metaplex DAS API 10 | * @param agent SolanaAgentKit instance 11 | * @param params Parameters for fetching assets by authority 12 | * @returns List of assets associated with the given authority 13 | */ 14 | export async function get_assets_by_authority( 15 | agent: SolanaAgentKit, 16 | params: GetAssetsByAuthorityRpcInput, 17 | ) { 18 | const umi = createUmi(agent.connection.rpcEndpoint).use(dasApi()); 19 | return await umi.rpc.getAssetsByAuthority(params); 20 | } 21 | -------------------------------------------------------------------------------- /src/tools/metaplex/get_assets_by_creator.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../agent"; 2 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 3 | import { 4 | dasApi, 5 | GetAssetsByCreatorRpcInput, 6 | } from "@metaplex-foundation/digital-asset-standard-api"; 7 | 8 | /** 9 | * Fetch assets by creator using the Metaplex DAS API 10 | * @param agent SolanaAgentKit instance 11 | * @param params Parameters for fetching assets by creator 12 | * @returns List of assets created by the specified creator 13 | */ 14 | export async function get_assets_by_creator( 15 | agent: SolanaAgentKit, 16 | params: GetAssetsByCreatorRpcInput, 17 | ) { 18 | const umi = createUmi(agent.connection.rpcEndpoint).use(dasApi()); 19 | return await umi.rpc.getAssetsByCreator(params); 20 | } 21 | -------------------------------------------------------------------------------- /src/tools/metaplex/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./deploy_collection"; 2 | export * from "./mint_nft"; 3 | export * from "./deploy_token"; 4 | export * from "./get_asset"; 5 | export * from "./get_assets_by_authority"; 6 | export * from "./get_assets_by_creator"; 7 | -------------------------------------------------------------------------------- /src/tools/meteora/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_meteora_dlmm_pool"; 2 | export * from "./create_meteora_dynamic_amm_pool"; 3 | -------------------------------------------------------------------------------- /src/tools/openbook/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./openbook_create_market"; 2 | -------------------------------------------------------------------------------- /src/tools/orca/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./orca_close_position"; 2 | export * from "./orca_create_clmm"; 3 | export * from "./orca_create_single_sided_liquidity_pool"; 4 | export * from "./orca_fetch_positions"; 5 | export * from "./orca_open_centered_position_with_liquidity"; 6 | export * from "./orca_open_single_sided_position"; 7 | -------------------------------------------------------------------------------- /src/tools/pumpfun/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./launch_pumpfun_token"; 2 | -------------------------------------------------------------------------------- /src/tools/pyth/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./pyth_fetch_price"; 2 | -------------------------------------------------------------------------------- /src/tools/raydium/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./raydium_create_ammV4"; 2 | export * from "./raydium_create_clmm"; 3 | export * from "./raydium_create_cpmm"; 4 | -------------------------------------------------------------------------------- /src/tools/rugcheck/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./rugcheck"; 2 | -------------------------------------------------------------------------------- /src/tools/sendarcade/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./rock_paper_scissor"; 2 | -------------------------------------------------------------------------------- /src/tools/sns/get_all_registered_all_domains.ts: -------------------------------------------------------------------------------- 1 | import { getAllDomains } from "@bonfida/spl-name-service"; 2 | import { SolanaAgentKit } from "../../agent"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | import { getAllDomainsTLDs } from "../alldomains/get_all_domains_tlds"; 5 | 6 | /** 7 | * Get all registered domains across all TLDs 8 | * @param agent SolanaAgentKit instance 9 | * @returns Array of all registered domain names with their TLDs 10 | */ 11 | export async function getAllRegisteredAllDomains( 12 | agent: SolanaAgentKit, 13 | ): Promise { 14 | try { 15 | // First get all TLDs 16 | const tlds = await getAllDomainsTLDs(agent); 17 | const allDomains: string[] = []; 18 | 19 | // For each TLD, fetch all registered domains 20 | for (const tld of tlds) { 21 | const domains = await getAllDomains( 22 | agent.connection, 23 | new PublicKey("namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX"), 24 | ); 25 | 26 | // Add domains with TLD suffix 27 | domains.forEach((domain) => { 28 | allDomains.push(`${domain}.${tld}`); 29 | }); 30 | } 31 | 32 | return allDomains; 33 | } catch (error: any) { 34 | throw new Error(`Failed to fetch all registered domains: ${error.message}`); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/tools/sns/get_main_all_domains_domain.ts: -------------------------------------------------------------------------------- 1 | import { getFavoriteDomain as _getFavoriteDomain } from "@bonfida/spl-name-service"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | 4 | /** 5 | * Get the user's main/favorite domain for a SolanaAgentKit instance 6 | * @param agent SolanaAgentKit instance 7 | * @param owner Owner's public key 8 | * @returns Promise resolving to the main domain name or null if not found 9 | */ 10 | export async function getMainAllDomainsDomain( 11 | agent: any, 12 | owner: PublicKey, 13 | ): Promise { 14 | let mainDomain = null; 15 | try { 16 | mainDomain = await _getFavoriteDomain(agent.connection, owner); 17 | return mainDomain.stale ? null : mainDomain.reverse; 18 | } catch (error: any) { 19 | console.error(error); 20 | return null; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tools/sns/get_primary_domain.ts: -------------------------------------------------------------------------------- 1 | import { getPrimaryDomain as _getPrimaryDomain } from "@bonfida/spl-name-service"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | import { SolanaAgentKit } from "../../agent"; 4 | 5 | /** 6 | * Retrieves the primary .sol domain associated with a given Solana public key. 7 | * 8 | * This function queries the Bonfida SPL Name Service to get the primary .sol domain for 9 | * a specified Solana public key. If the primary domain is stale or an error occurs during 10 | * the resolution, it throws an error. 11 | * 12 | * @param agent SolanaAgentKit instance 13 | * @param account The Solana public key for which to retrieve the primary domain 14 | * @returns A promise that resolves to the primary .sol domain as a string 15 | * @throws Error if the domain is stale or if the domain resolution fails 16 | */ 17 | export async function getPrimaryDomain( 18 | agent: SolanaAgentKit, 19 | account: PublicKey, 20 | ): Promise { 21 | try { 22 | const { reverse, stale } = await _getPrimaryDomain( 23 | agent.connection, 24 | account, 25 | ); 26 | if (stale) { 27 | throw new Error( 28 | `Primary domain is stale for account: ${account.toBase58()}`, 29 | ); 30 | } 31 | return reverse; 32 | } catch (error: any) { 33 | console.error(error); 34 | throw new Error( 35 | `Failed to get primary domain for account: ${account.toBase58()}`, 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/tools/sns/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_all_registered_all_domains"; 2 | export * from "./get_main_all_domains_domain"; 3 | export * from "./get_primary_domain"; 4 | export * from "./register_domain"; 5 | export * from "./resolve_sol_domain"; 6 | -------------------------------------------------------------------------------- /src/tools/sns/resolve_sol_domain.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "@bonfida/spl-name-service"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | import { SolanaAgentKit } from "../../index"; 4 | 5 | /** 6 | * Resolves a .sol domain to a Solana PublicKey. 7 | * 8 | * This function uses the Bonfida SPL Name Service to resolve a given .sol domain 9 | * to the corresponding Solana PublicKey. The domain can be provided with or without 10 | * the .sol suffix. 11 | * 12 | * @param agent SolanaAgentKit instance 13 | * @param domain The .sol domain to resolve. This can be provided with or without the .sol TLD suffix 14 | * @returns A promise that resolves to the corresponding Solana PublicKey 15 | * @throws Error if the domain resolution fails 16 | */ 17 | export async function resolveSolDomain( 18 | agent: SolanaAgentKit, 19 | domain: string, 20 | ): Promise { 21 | if (!domain || typeof domain !== "string") { 22 | throw new Error("Invalid domain. Expected a non-empty string."); 23 | } 24 | 25 | try { 26 | return await resolve(agent.connection, domain); 27 | } catch (error: any) { 28 | console.error(error); 29 | throw new Error(`Failed to resolve domain: ${domain}`); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/tools/solana/get_balance.ts: -------------------------------------------------------------------------------- 1 | import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; 2 | import { SolanaAgentKit } from "../../index"; 3 | 4 | /** 5 | * Get the balance of SOL or an SPL token for the agent's wallet 6 | * @param agent - SolanaAgentKit instance 7 | * @param token_address - Optional SPL token mint address. If not provided, returns SOL balance 8 | * @returns Promise resolving to the balance as a number (in UI units) or null if account doesn't exist 9 | */ 10 | export async function get_balance( 11 | agent: SolanaAgentKit, 12 | token_address?: PublicKey, 13 | ): Promise { 14 | if (!token_address) { 15 | return ( 16 | (await agent.connection.getBalance(agent.wallet_address)) / 17 | LAMPORTS_PER_SOL 18 | ); 19 | } 20 | 21 | const token_account = 22 | await agent.connection.getTokenAccountBalance(token_address); 23 | return token_account.value.uiAmount || 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/tools/solana/get_tps.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../index"; 2 | 3 | export async function getTPS(agent: SolanaAgentKit): Promise { 4 | const perfSamples = await agent.connection.getRecentPerformanceSamples(); 5 | 6 | if ( 7 | !perfSamples.length || 8 | !perfSamples[0]?.numTransactions || 9 | !perfSamples[0]?.samplePeriodSecs 10 | ) { 11 | throw new Error("No performance samples available"); 12 | } 13 | 14 | const tps = perfSamples[0].numTransactions / perfSamples[0].samplePeriodSecs; 15 | 16 | return tps; 17 | } 18 | -------------------------------------------------------------------------------- /src/tools/solana/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get_tps"; 2 | export * from "./request_faucet_funds"; 3 | export * from "./close_empty_token_accounts"; 4 | export * from "./transfer"; 5 | export * from "./get_balance"; 6 | export * from "./get_balance_other"; 7 | export * from "./get_token_balances"; 8 | -------------------------------------------------------------------------------- /src/tools/solana/request_faucet_funds.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../index"; 2 | import { LAMPORTS_PER_SOL } from "@solana/web3.js"; 3 | 4 | /** 5 | * Request SOL from the Solana faucet (devnet/testnet only) 6 | * @param agent - SolanaAgentKit instance 7 | * @returns Transaction signature 8 | * @throws Error if the request fails or times out 9 | */ 10 | export async function request_faucet_funds( 11 | agent: SolanaAgentKit, 12 | ): Promise { 13 | const tx = await agent.connection.requestAirdrop( 14 | agent.wallet_address, 15 | 5 * LAMPORTS_PER_SOL, 16 | ); 17 | 18 | const latestBlockHash = await agent.connection.getLatestBlockhash(); 19 | 20 | await agent.connection.confirmTransaction({ 21 | signature: tx, 22 | blockhash: latestBlockHash.blockhash, 23 | lastValidBlockHeight: latestBlockHash.lastValidBlockHeight, 24 | }); 25 | 26 | return tx; 27 | } 28 | -------------------------------------------------------------------------------- /src/tools/solayer/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./stake_with_solayer"; 2 | -------------------------------------------------------------------------------- /src/tools/squads/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_multisig"; 2 | export * from "./create_proposal"; 3 | export * from "./approve_proposal"; 4 | export * from "./deposit_to_treasury"; 5 | export * from "./execute_proposal"; 6 | export * from "./reject_proposal"; 7 | export * from "./transfer_from_treasury"; 8 | -------------------------------------------------------------------------------- /src/tools/tensor/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./tensor_trade"; 2 | -------------------------------------------------------------------------------- /src/tools/tiplink/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create_tiplinks"; 2 | -------------------------------------------------------------------------------- /src/tools/voltr/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./voltr_deposit_strategy"; 2 | export * from "./voltr_withdraw_strategy"; 3 | export * from "./voltr_get_position_values"; 4 | -------------------------------------------------------------------------------- /src/tools/voltr/voltr_get_position_values.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../../agent"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | import { VoltrClient } from "@voltr/vault-sdk"; 4 | 5 | /** 6 | * Gets the value of assets in a Voltr vault 7 | * @param agent SolanaAgentKit instance 8 | * @param vault Public key of the target vault 9 | * @returns Position and total values for the vault 10 | */ 11 | export async function voltrGetPositionValues( 12 | agent: SolanaAgentKit, 13 | vault: PublicKey, 14 | ): Promise { 15 | const vc = new VoltrClient(agent.connection, agent.wallet); 16 | const positionAndTotalValues = 17 | await vc.getPositionAndTotalValuesForVault(vault); 18 | 19 | return JSON.stringify(positionAndTotalValues); 20 | } 21 | -------------------------------------------------------------------------------- /src/types/action.ts: -------------------------------------------------------------------------------- 1 | import { SolanaAgentKit } from "../agent"; 2 | import { z } from "zod"; 3 | 4 | /** 5 | * Example of an action with input and output 6 | */ 7 | export interface ActionExample { 8 | input: Record; 9 | output: Record; 10 | explanation: string; 11 | } 12 | 13 | /** 14 | * Handler function type for executing the action 15 | */ 16 | export type Handler = ( 17 | agent: SolanaAgentKit, 18 | input: Record, 19 | ) => Promise>; 20 | 21 | /** 22 | * Main Action interface inspired by ELIZA 23 | * This interface makes it easier to implement actions across different frameworks 24 | */ 25 | export interface Action { 26 | /** 27 | * Unique name of the action 28 | */ 29 | name: string; 30 | 31 | /** 32 | * Alternative names/phrases that can trigger this action 33 | */ 34 | similes: string[]; 35 | 36 | /** 37 | * Detailed description of what the action does 38 | */ 39 | description: string; 40 | 41 | /** 42 | * Array of example inputs and outputs for the action 43 | * Each inner array represents a group of related examples 44 | */ 45 | examples: ActionExample[][]; 46 | 47 | /** 48 | * Zod schema for input validation 49 | */ 50 | schema: z.ZodType; 51 | 52 | /** 53 | * Function that executes the action 54 | */ 55 | handler: Handler; 56 | } 57 | -------------------------------------------------------------------------------- /src/utils/keypair.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Keypair, 3 | PublicKey, 4 | Transaction, 5 | VersionedTransaction, 6 | } from "@solana/web3.js"; 7 | import bs58 from "bs58"; 8 | 9 | export const keypair = Keypair.generate(); 10 | 11 | console.log(keypair.publicKey.toString()); 12 | console.log(bs58.encode(keypair.secretKey)); 13 | 14 | export class Wallet { 15 | private _signer: Keypair; 16 | 17 | constructor(signer: Keypair) { 18 | this._signer = signer; 19 | } 20 | 21 | async signTransaction( 22 | tx: T, 23 | ): Promise { 24 | if (tx instanceof Transaction) { 25 | tx.sign(this._signer); 26 | } else if (tx instanceof VersionedTransaction) { 27 | tx.sign([this._signer]); 28 | } else { 29 | throw new Error("Unsupported transaction type"); 30 | } 31 | return tx; 32 | } 33 | 34 | async signAllTransactions( 35 | txs: T[], 36 | ): Promise { 37 | return Promise.all(txs.map((tx) => this.signTransaction(tx))); 38 | } 39 | 40 | get publicKey(): PublicKey { 41 | return this._signer.publicKey; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/vercel-ai/index.ts: -------------------------------------------------------------------------------- 1 | import { tool, type CoreTool } from "ai"; 2 | import { SolanaAgentKit } from "../agent"; 3 | import { executeAction } from "../utils/actionExecutor"; 4 | import { ACTIONS } from "../actions"; 5 | 6 | export function createSolanaTools( 7 | solanaAgentKit: SolanaAgentKit, 8 | ): Record { 9 | const tools: Record = {}; 10 | const actionKeys = Object.keys(ACTIONS); 11 | 12 | for (const key of actionKeys) { 13 | const action = ACTIONS[key as keyof typeof ACTIONS]; 14 | tools[key] = tool({ 15 | // @ts-expect-error Value matches type however TS still shows error 16 | id: action.name, 17 | description: ` 18 | ${action.description} 19 | 20 | Similes: ${action.similes.map( 21 | (simile) => ` 22 | ${simile} 23 | `, 24 | )} 25 | `.slice(0, 1023), 26 | parameters: action.schema, 27 | execute: async (params) => 28 | await executeAction(action, solanaAgentKit, params), 29 | }); 30 | } 31 | 32 | return tools; 33 | } 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "lib": ["es2020", "dom"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "outDir": "./dist", 10 | "rootDir": "./src", 11 | "strict": true, 12 | "noImplicitAny": true, 13 | "strictBindCallApply": true, 14 | "strictPropertyInitialization": true, 15 | "noImplicitThis": true, 16 | "useUnknownInCatchVariables": true, 17 | "alwaysStrict": true, 18 | "exactOptionalPropertyTypes": true, 19 | "noImplicitReturns": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noImplicitOverride": true, 22 | "esModuleInterop": true, 23 | "forceConsistentCasingInFileNames": true, 24 | "skipLibCheck": true, 25 | }, 26 | "include": ["src/**/*"], 27 | "exclude": ["node_modules", "dist", "**/*.test.ts"] 28 | } 29 | --------------------------------------------------------------------------------