@elizaos/plugin-wallet 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/auto-enable.ts +76 -0
- package/dist/LpManagementService-BWrQ5-cO.mjs +353 -0
- package/dist/MockLpService-D_Apn4Fd.mjs +99 -0
- package/dist/aerodrome-CfnESC32.mjs +890 -0
- package/dist/chunk-hT5z_Zn9.mjs +35 -0
- package/dist/index.d.mts +34727 -0
- package/dist/index.mjs +21590 -0
- package/dist/lib/server-wallet-trade.d.mts +34 -0
- package/dist/lib/server-wallet-trade.mjs +306 -0
- package/dist/meteora-BPX39hZo.mjs +22640 -0
- package/dist/orca-Bybp1HXO.mjs +249 -0
- package/dist/pancakeswp-CkEXlXti.mjs +604 -0
- package/dist/plugin-ZO_MTyd0.mjs +529 -0
- package/dist/raydium-rfaM9yEf.mjs +539 -0
- package/dist/sdk/index.d.mts +32492 -0
- package/dist/sdk/index.mjs +6415 -0
- package/dist/types-D5252NZk.mjs +487 -0
- package/dist/uniswap-CReXgXVN.mjs +573 -0
- package/dist/wallet-action.d.mts +6 -0
- package/dist/wallet-action.mjs +820 -0
- package/package.json +152 -0
- package/src/actions/failure-codes.ts +79 -0
- package/src/actions/index.ts +1 -0
- package/src/analytics/birdeye/actions/wallet-search-address.ts +9 -0
- package/src/analytics/birdeye/birdeye-task.ts +175 -0
- package/src/analytics/birdeye/birdeye.ts +813 -0
- package/src/analytics/birdeye/constants.ts +74 -0
- package/src/analytics/birdeye/providers/agent-portfolio-provider.ts +18 -0
- package/src/analytics/birdeye/providers/market.ts +227 -0
- package/src/analytics/birdeye/providers/portfolio-factory.test.ts +138 -0
- package/src/analytics/birdeye/providers/portfolio-factory.ts +252 -0
- package/src/analytics/birdeye/providers/trending.ts +365 -0
- package/src/analytics/birdeye/providers/wallet.ts +14 -0
- package/src/analytics/birdeye/search-category.test.ts +207 -0
- package/src/analytics/birdeye/search-category.ts +506 -0
- package/src/analytics/birdeye/service.ts +992 -0
- package/src/analytics/birdeye/tasks/birdeye.ts +232 -0
- package/src/analytics/birdeye/types/api/common.ts +305 -0
- package/src/analytics/birdeye/types/api/defi.ts +220 -0
- package/src/analytics/birdeye/types/api/pair.ts +200 -0
- package/src/analytics/birdeye/types/api/search.ts +86 -0
- package/src/analytics/birdeye/types/api/token.ts +635 -0
- package/src/analytics/birdeye/types/api/trader.ts +76 -0
- package/src/analytics/birdeye/types/api/wallet.ts +181 -0
- package/src/analytics/birdeye/types/shared.ts +106 -0
- package/src/analytics/birdeye/utils.ts +700 -0
- package/src/analytics/dexscreener/errors.ts +28 -0
- package/src/analytics/dexscreener/index.ts +3 -0
- package/src/analytics/dexscreener/search-category.test.ts +49 -0
- package/src/analytics/dexscreener/search-category.ts +42 -0
- package/src/analytics/dexscreener/service.ts +595 -0
- package/src/analytics/dexscreener/types.ts +128 -0
- package/src/analytics/lpinfo/index.d.ts +7 -0
- package/src/analytics/lpinfo/index.ts +52 -0
- package/src/analytics/lpinfo/kamino/README.md +102 -0
- package/src/analytics/lpinfo/kamino/index.ts +24 -0
- package/src/analytics/lpinfo/kamino/providers/kaminoLiquidityProvider.ts +422 -0
- package/src/analytics/lpinfo/kamino/providers/kaminoPoolProvider.ts +365 -0
- package/src/analytics/lpinfo/kamino/providers/kaminoProvider.ts +496 -0
- package/src/analytics/lpinfo/kamino/services/kaminoLiquidityService.ts +1123 -0
- package/src/analytics/lpinfo/kamino/services/kaminoService.ts +758 -0
- package/src/analytics/lpinfo/steer/README.md +169 -0
- package/src/analytics/lpinfo/steer/index.ts +23 -0
- package/src/analytics/lpinfo/steer/providers/steerLiquidityProvider.ts +544 -0
- package/src/analytics/lpinfo/steer/services/steerLiquidityService.ts +1690 -0
- package/src/analytics/lpinfo/steer/steer-display-types.ts +99 -0
- package/src/analytics/news/index.ts +52 -0
- package/src/analytics/news/interfaces/types.ts +222 -0
- package/src/analytics/news/providers/defiNewsProvider.ts +734 -0
- package/src/analytics/news/services/newsDataService.ts +332 -0
- package/src/analytics/news/utils/formatters.ts +151 -0
- package/src/analytics/token-info/action.ts +240 -0
- package/src/analytics/token-info/index.ts +3 -0
- package/src/analytics/token-info/params.ts +215 -0
- package/src/analytics/token-info/providers.ts +681 -0
- package/src/analytics/token-info/service.ts +168 -0
- package/src/analytics/token-info/types.ts +74 -0
- package/src/audit/audit-log.ts +45 -0
- package/src/browser-shim/build-shim.ts +123 -0
- package/src/browser-shim/index.ts +5 -0
- package/src/browser-shim/shim.template.js +563 -0
- package/src/chains/evm/.github/workflows/npm-deploy.yml +112 -0
- package/src/chains/evm/LICENSE +21 -0
- package/src/chains/evm/README.md +106 -0
- package/src/chains/evm/actions/helpers.ts +147 -0
- package/src/chains/evm/actions/swap.ts +839 -0
- package/src/chains/evm/actions/transfer.ts +254 -0
- package/src/chains/evm/biome.json +61 -0
- package/src/chains/evm/bridge-router.ts +660 -0
- package/src/chains/evm/build.ts +89 -0
- package/src/chains/evm/chain-handler.ts +416 -0
- package/src/chains/evm/constants.ts +23 -0
- package/src/chains/evm/contracts/artifacts/OZGovernor.json +1707 -0
- package/src/chains/evm/contracts/artifacts/TimelockController.json +1007 -0
- package/src/chains/evm/contracts/artifacts/VoteToken.json +895 -0
- package/src/chains/evm/dex/aerodrome/index.ts +34 -0
- package/src/chains/evm/dex/aerodrome/services/AerodromeLpService.ts +558 -0
- package/src/chains/evm/dex/aerodrome/types.ts +318 -0
- package/src/chains/evm/dex/pancakeswp/index.ts +35 -0
- package/src/chains/evm/dex/pancakeswp/services/PancakeSwapV3LpService.ts +743 -0
- package/src/chains/evm/dex/pancakeswp/types.ts +65 -0
- package/src/chains/evm/dex/uniswap/index.ts +35 -0
- package/src/chains/evm/dex/uniswap/services/UniswapV3LpService.ts +759 -0
- package/src/chains/evm/dex/uniswap/types.ts +390 -0
- package/src/chains/evm/generated/specs/spec-helpers.ts +73 -0
- package/src/chains/evm/generated/specs/specs.ts +151 -0
- package/src/chains/evm/gov-router.ts +250 -0
- package/src/chains/evm/index.browser.ts +16 -0
- package/src/chains/evm/index.ts +31 -0
- package/src/chains/evm/prompts.ts +193 -0
- package/src/chains/evm/providers/get-balance.ts +123 -0
- package/src/chains/evm/providers/wallet.ts +715 -0
- package/src/chains/evm/routes/sign.ts +333 -0
- package/src/chains/evm/rpc-providers.ts +410 -0
- package/src/chains/evm/service.ts +140 -0
- package/src/chains/evm/templates/index.ts +10 -0
- package/src/chains/evm/types/index.ts +432 -0
- package/src/chains/evm/vitest.config.ts +18 -0
- package/src/chains/registry.ts +668 -0
- package/src/chains/solana/README.md +367 -0
- package/src/chains/wallet-action.ts +533 -0
- package/src/chains/wallet-router.test.ts +296 -0
- package/src/contracts.ts +65 -0
- package/src/core-augmentation.ts +10 -0
- package/src/index.ts +71 -0
- package/src/lib/server-wallet-trade.ts +192 -0
- package/src/lib/wallet-export-guard.ts +330 -0
- package/src/lp/actions/liquidity.ts +827 -0
- package/src/lp/e2e/real-token-tests.ts +428 -0
- package/src/lp/e2e/scenarios.ts +470 -0
- package/src/lp/e2e/test-utils.ts +145 -0
- package/src/lp/lp-manager-entry.ts +303 -0
- package/src/lp/services/ConcentratedLiquidityService.ts +120 -0
- package/src/lp/services/DexInteractionService.ts +226 -0
- package/src/lp/services/LpManagementService.test.ts +148 -0
- package/src/lp/services/LpManagementService.ts +632 -0
- package/src/lp/services/UserLpProfileService.ts +163 -0
- package/src/lp/services/VaultService.ts +153 -0
- package/src/lp/services/YieldOptimizationService.ts +344 -0
- package/src/lp/services/__tests__/MockLpService.ts +146 -0
- package/src/lp/tasks/LpAutoRebalanceTask.ts +117 -0
- package/src/lp/tasks/__tests__/LpAutoRebalanceTask.test.ts +370 -0
- package/src/lp/types.ts +582 -0
- package/src/lp/utils/solanaClient.ts +143 -0
- package/src/plugin.ts +125 -0
- package/src/policy/policy.ts +19 -0
- package/src/providers/canonical-provider.ts +27 -0
- package/src/providers/unified-wallet-provider.ts +79 -0
- package/src/register-routes.ts +11 -0
- package/src/routes/plugin.ts +47 -0
- package/src/routes/wallet-market-overview-route.ts +869 -0
- package/src/sdk/abi.ts +258 -0
- package/src/sdk/bridge/abis.ts +126 -0
- package/src/sdk/bridge/client.ts +518 -0
- package/src/sdk/bridge/index.ts +56 -0
- package/src/sdk/bridge/solana.ts +604 -0
- package/src/sdk/bridge/types.ts +202 -0
- package/src/sdk/convenience.ts +347 -0
- package/src/sdk/escrow/MutualStakeEscrow.ts +480 -0
- package/src/sdk/escrow/types.ts +64 -0
- package/src/sdk/escrow/verifiers.ts +73 -0
- package/src/sdk/identity/erc8004.ts +692 -0
- package/src/sdk/identity/reputation.ts +449 -0
- package/src/sdk/identity/uaid.ts +497 -0
- package/src/sdk/identity/validation.ts +372 -0
- package/src/sdk/index.ts +763 -0
- package/src/sdk/policy/SpendingPolicy.ts +260 -0
- package/src/sdk/policy/UptoBillingPolicy.ts +320 -0
- package/src/sdk/router/PaymentRouter.ts +215 -0
- package/src/sdk/router/index.ts +8 -0
- package/src/sdk/swap/SwapModule.ts +310 -0
- package/src/sdk/swap/abi.ts +117 -0
- package/src/sdk/swap/index.ts +34 -0
- package/src/sdk/swap/types.ts +135 -0
- package/src/sdk/tokens/decimals.ts +140 -0
- package/src/sdk/tokens/registry.ts +911 -0
- package/src/sdk/tokens/solana.ts +419 -0
- package/src/sdk/tokens/transfers.ts +327 -0
- package/src/sdk/types.ts +158 -0
- package/src/sdk/wallet-core.ts +115 -0
- package/src/sdk/x402/budget.ts +168 -0
- package/src/sdk/x402/chains/abstract/index.ts +280 -0
- package/src/sdk/x402/client.ts +320 -0
- package/src/sdk/x402/index.ts +46 -0
- package/src/sdk/x402/middleware.ts +92 -0
- package/src/sdk/x402/multi-asset.ts +144 -0
- package/src/sdk/x402/types.ts +156 -0
- package/src/services/wallet-backend-service.ts +328 -0
- package/src/types/wallet-router.ts +227 -0
- package/src/utils/intent-trajectory.ts +106 -0
- package/src/wallet/backend.ts +62 -0
- package/src/wallet/errors.ts +49 -0
- package/src/wallet/index.ts +27 -0
- package/src/wallet/local-eoa-backend.ts +201 -0
- package/src/wallet/pending.ts +60 -0
- package/src/wallet/select-backend.ts +47 -0
- package/src/wallet/steward-backend.ts +161 -0
- package/src/wallet-action.ts +1 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
export const DEFAULT_MAX_RETRIES = 3;
|
|
3
|
+
|
|
4
|
+
export const BIRDEYE_SERVICE_NAME = "birdeye";
|
|
5
|
+
|
|
6
|
+
export const DEFAULT_SUPPORTED_SYMBOLS = {
|
|
7
|
+
SOL: "So11111111111111111111111111111111111111112",
|
|
8
|
+
BTC: "qfnqNqs3nCAHjnyCgLRDbBtq4p2MtHZxw8YjSyYhPoL",
|
|
9
|
+
ETH: "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
|
|
10
|
+
Example: "2weMjPLLybRMMva1fM3U31goWWrCpF59CHWNhnCJ9Vyh",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const API_BASE_URL = "https://public-api.birdeye.so";
|
|
14
|
+
|
|
15
|
+
export const RETRY_DELAY_MS = 2_000;
|
|
16
|
+
|
|
17
|
+
export const BIRDEYE_ENDPOINTS = {
|
|
18
|
+
defi: {
|
|
19
|
+
networks: "/defi/networks", // https://docs.birdeye.so/reference/get_defi-networks
|
|
20
|
+
price: "/defi/price", // https://docs.birdeye.so/reference/get_defi-price
|
|
21
|
+
price_multi: "/defi/multi_price", // https://docs.birdeye.so/reference/get_defi-multi-price
|
|
22
|
+
price_multi_POST: "/defi/multi_price", // https://docs.birdeye.so/reference/post_defi-multi-price
|
|
23
|
+
history_price: "/defi/history_price", // https://docs.birdeye.so/reference/get_defi-history-price
|
|
24
|
+
historical_price_unix: "/defi/historical_price_unix", // https://docs.birdeye.so/reference/get_defi-historical-price-unix
|
|
25
|
+
trades_token: "/defi/txs/token", // https://docs.birdeye.so/reference/get_defi-txs-token
|
|
26
|
+
trades_pair: "/defi/txs/pair", // https://docs.birdeye.so/reference/get_defi-txs-pair
|
|
27
|
+
trades_token_seek: "/defi/txs/token/seek_by_time", // https://docs.birdeye.so/reference/get_defi-txs-token-seek-by-time
|
|
28
|
+
trades_pair_seek: "/defi/txs/pair/seek_by_time", // https://docs.birdeye.so/reference/get_defi-txs-pair-seek-by-time
|
|
29
|
+
ohlcv: "/defi/ohlcv", // https://docs.birdeye.so/reference/get_defi-ohlcv
|
|
30
|
+
ohlcv_pair: "/defi/ohlcv/pair", // https://docs.birdeye.so/reference/get_defi-ohlcv-pair
|
|
31
|
+
ohlcv_base_quote: "/defi/ohlcv/base_quote", // https://docs.birdeye.so/reference/get_defi-ohlcv-base-quote
|
|
32
|
+
price_volume: "/defi/price_volume/single", // https://docs.birdeye.so/reference/get_defi-price-volume-single
|
|
33
|
+
price_volume_multi: "/defi/price_volume/multi", // https://docs.birdeye.so/reference/get_defi-price-volume-multi
|
|
34
|
+
price_volume_multi_POST: "/defi/price_volume/multi", // https://docs.birdeye.so/reference/post_defi-price-volume-multi
|
|
35
|
+
},
|
|
36
|
+
token: {
|
|
37
|
+
list_all: "/defi/tokenlist", // https://docs.birdeye.so/reference/get_defi-tokenlist
|
|
38
|
+
security: "/defi/token_security", // https://docs.birdeye.so/reference/get_defi-token-security
|
|
39
|
+
overview: "/defi/token_overview", // https://docs.birdeye.so/reference/get_defi-token-overview
|
|
40
|
+
creation_info: "/defi/token_creation_info", // https://docs.birdeye.so/reference/get_defi-token-creation-info
|
|
41
|
+
trending: "/defi/token_trending", // https://docs.birdeye.so/reference/get_defi-token-trending
|
|
42
|
+
list_all_v2_POST: "/defi/v2/tokens/all", // https://docs.birdeye.so/reference/post_defi-v2-tokens-all
|
|
43
|
+
new_listing: "/defi/v2/tokens/new_listing", // https://docs.birdeye.so/reference/get_defi-v2-tokens-new-listing
|
|
44
|
+
top_traders: "/defi/v2/tokens/top_traders", // https://docs.birdeye.so/reference/get_defi-v2-tokens-top-traders
|
|
45
|
+
all_markets: "/defi/v2/markets", // https://docs.birdeye.so/reference/get_defi-v2-markets
|
|
46
|
+
metadata_single: "/defi/v3/token/meta-data/single", // https://docs.birdeye.so/reference/get_defi-v3-token-meta-data-single
|
|
47
|
+
metadata_multi: "/defi/v3/token/meta-data/multiple", // https://docs.birdeye.so/reference/get_defi-v3-token-meta-data-multiple
|
|
48
|
+
market_data: "/defi/v3/token/market-data", // https://docs.birdeye.so/reference/get_defi-v3-token-market-data
|
|
49
|
+
trade_data_single: "/defi/v3/token/trade-data/single", // https://docs.birdeye.so/reference/get_defi-v3-token-trade-data-single
|
|
50
|
+
trade_data_multi: "/defi/v3/token/trade-data/multiple", // https://docs.birdeye.so/reference/get_defi-v3-token-trade-data-multiple
|
|
51
|
+
holders: "/defi/v3/token/holder", // https://docs.birdeye.so/reference/get_defi-v3-token-holder
|
|
52
|
+
mint_burn: "/defi/v3/token/mint-burn-txs", // https://docs.birdeye.so/reference/get_defi-v3-token-mint-burn-txs
|
|
53
|
+
},
|
|
54
|
+
wallet: {
|
|
55
|
+
networks: "/v1/wallet/list_supported_chain", // https://docs.birdeye.so/reference/get_v1-wallet-list-supported-chain
|
|
56
|
+
portfolio: "/v1/wallet/token_list", // https://docs.birdeye.so/reference/get_v1-wallet-token-list
|
|
57
|
+
portfolio_multichain: "/v1/wallet/multichain_token_list", // https://docs.birdeye.so/reference/get_v1-wallet-multichain-token-list
|
|
58
|
+
token_balance: "/v1/wallet/token_balance", // https://docs.birdeye.so/reference/get_v1-wallet-token-balance
|
|
59
|
+
transaction_history: "/v1/wallet/tx_list", // https://docs.birdeye.so/reference/get_v1-wallet-tx-list
|
|
60
|
+
transaction_history_multichain: "/v1/wallet/multichain_tx_list", // https://docs.birdeye.so/reference/get_v1-wallet-multichain-tx-list
|
|
61
|
+
transaction_simulation_POST: "/v1/wallet/simulate", // https://docs.birdeye.so/reference/post_v1-wallet-simulate
|
|
62
|
+
},
|
|
63
|
+
trader: {
|
|
64
|
+
gainers_losers: "/trader/gainers-losers", // https://docs.birdeye.so/reference/get_trader-gainers-losers
|
|
65
|
+
trades_seek: "/trader/txs/seek_by_time", // https://docs.birdeye.so/reference/get_trader-txs-seek-by-time
|
|
66
|
+
},
|
|
67
|
+
pair: {
|
|
68
|
+
overview_multi: "/defi/v3/pair/overview/multiple", // https://docs.birdeye.so/reference/get_defi-v3-pair-overview-multiple
|
|
69
|
+
overview_single: "/defi/v3/pair/overview/single", // https://docs.birdeye.so/reference/get_defi-v3-pair-overview-single
|
|
70
|
+
},
|
|
71
|
+
search: {
|
|
72
|
+
token_market: "/defi/v3/search", // https://docs.birdeye.so/reference/get_defi-v3-search
|
|
73
|
+
},
|
|
74
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
import {
|
|
3
|
+
createBirdeyePortfolioProvider,
|
|
4
|
+
formatPortfolio,
|
|
5
|
+
} from "./portfolio-factory";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Agent portfolio data provider that queries Birdeye API for the agent's wallet address.
|
|
9
|
+
* When a wallet address is set, this provider fetches current token balances and makes
|
|
10
|
+
* compact JSON portfolio context available to the planner.
|
|
11
|
+
*/
|
|
12
|
+
export const agentPortfolioProvider = createBirdeyePortfolioProvider({
|
|
13
|
+
name: "BIRDEYE_WALLET_PORTFOLIO",
|
|
14
|
+
description: "Birdeye token balances for the agent wallet",
|
|
15
|
+
descriptionCompressed: "Read Birdeye token balances for wallet.",
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export { formatPortfolio };
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
import type { IAgentRuntime, Memory, Provider, State } from "@elizaos/core";
|
|
3
|
+
//import { addHeader, composeActionExamples, formatActionNames, formatActions } from '@elizaos/core';
|
|
4
|
+
//import type { IToken } from '../types';
|
|
5
|
+
import { BIRDEYE_SERVICE_NAME } from "../constants";
|
|
6
|
+
import type { CacheWrapper, GetCacheTimedOptions } from "../types/shared";
|
|
7
|
+
import { formatJsonScalar, formatJsonTable } from "../utils";
|
|
8
|
+
|
|
9
|
+
const MARKET_ROW_LIMIT = 12;
|
|
10
|
+
|
|
11
|
+
export async function getCacheTimed<T>(
|
|
12
|
+
runtime: IAgentRuntime,
|
|
13
|
+
key: string,
|
|
14
|
+
options: GetCacheTimedOptions = {},
|
|
15
|
+
): Promise<T | undefined> {
|
|
16
|
+
const wrapper = await runtime.getCache<CacheWrapper<T>>(key);
|
|
17
|
+
if (!wrapper) return;
|
|
18
|
+
if (options.notOlderThan) {
|
|
19
|
+
const diff = Date.now() - wrapper.setAt;
|
|
20
|
+
//console.log('checking notOlderThan', diff + 'ms', 'setAt', wrapper.setAt, 'asking', options.notOlderThan)
|
|
21
|
+
if (diff > options.notOlderThan) {
|
|
22
|
+
// no data
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// return data
|
|
27
|
+
return wrapper.data;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Provider for Birdeye market data
|
|
32
|
+
*
|
|
33
|
+
* @typedef {import('./Provider').Provider} Provider
|
|
34
|
+
* @typedef {import('./Runtime').IAgentRuntime} IAgentRuntime
|
|
35
|
+
* @typedef {import('./Memory').Memory} Memory
|
|
36
|
+
* @typedef {import('./State').State} State
|
|
37
|
+
* @typedef {import('./Action').Action} Action
|
|
38
|
+
*
|
|
39
|
+
* @type {Provider}
|
|
40
|
+
* @property {string} name - The name of the provider
|
|
41
|
+
* @property {string} description - Description of the provider
|
|
42
|
+
* @property {number} position - The position of the provider
|
|
43
|
+
* @property {Function} get - Asynchronous function to get actions that validate for a given message
|
|
44
|
+
*
|
|
45
|
+
* @param {IAgentRuntime} runtime - The agent runtime
|
|
46
|
+
* @param {Memory} message - The message memory
|
|
47
|
+
* @param {State} state - The state of the agent
|
|
48
|
+
* @returns {Object} Object containing data, values, and text related to actions
|
|
49
|
+
*/
|
|
50
|
+
export const marketProvider: Provider = {
|
|
51
|
+
name: "BIRDEYE_CRYPTOCURRENCY_MARKET_DATA",
|
|
52
|
+
description: "Birdeye get latest cryptocurrencies overview",
|
|
53
|
+
descriptionCompressed: "Read latest Birdeye cryptocurrency market overview.",
|
|
54
|
+
dynamic: true,
|
|
55
|
+
contexts: ["finance", "crypto", "wallet"],
|
|
56
|
+
contextGate: { anyOf: ["finance", "crypto", "wallet"] },
|
|
57
|
+
cacheStable: false,
|
|
58
|
+
cacheScope: "turn",
|
|
59
|
+
roleGate: { minRole: "USER" },
|
|
60
|
+
//position: -1,
|
|
61
|
+
get: async (runtime: IAgentRuntime, _message: Memory, _state: State) => {
|
|
62
|
+
try {
|
|
63
|
+
//console.log('BIRDEYE_CRYPTOCURRENCY_MARKET_DATA getting');
|
|
64
|
+
|
|
65
|
+
// define the market
|
|
66
|
+
// FIXME: get out of runtime.getSettings
|
|
67
|
+
const TOKEN_ADDRESSES = {
|
|
68
|
+
SOL: "So11111111111111111111111111111111111111112",
|
|
69
|
+
BTC: "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh", // wBTC
|
|
70
|
+
ETH: "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs", // wETH
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const hardcodedSolanaCA2SymbolMap = {
|
|
74
|
+
So11111111111111111111111111111111111111112: "SOL",
|
|
75
|
+
"3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh": "BTC", // wBTC
|
|
76
|
+
"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs": "ETH", // wETH
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// get the market
|
|
80
|
+
const CAs = Object.values(TOKEN_ADDRESSES);
|
|
81
|
+
|
|
82
|
+
// get services
|
|
83
|
+
const birdeyeService = runtime.getService(BIRDEYE_SERVICE_NAME) as
|
|
84
|
+
| {
|
|
85
|
+
getTokensMarketData?: (
|
|
86
|
+
chain: string,
|
|
87
|
+
addresses: string[],
|
|
88
|
+
) => Promise<
|
|
89
|
+
Record<
|
|
90
|
+
string,
|
|
91
|
+
{
|
|
92
|
+
symbol: string;
|
|
93
|
+
priceUsd: number;
|
|
94
|
+
priceChange24h: number;
|
|
95
|
+
liquidity: number;
|
|
96
|
+
}
|
|
97
|
+
>
|
|
98
|
+
>;
|
|
99
|
+
}
|
|
100
|
+
| undefined;
|
|
101
|
+
// want this for custom symbols
|
|
102
|
+
const solanaService = runtime.getService("chain_solana") as
|
|
103
|
+
| {
|
|
104
|
+
getTokensSymbols?: (
|
|
105
|
+
addresses: string[],
|
|
106
|
+
) => Promise<Record<string, string>>;
|
|
107
|
+
}
|
|
108
|
+
| undefined;
|
|
109
|
+
|
|
110
|
+
// Guard Birdeye service before invoking methods
|
|
111
|
+
if (
|
|
112
|
+
!birdeyeService ||
|
|
113
|
+
typeof birdeyeService.getTokensMarketData !== "function"
|
|
114
|
+
) {
|
|
115
|
+
runtime.logger?.error(
|
|
116
|
+
"Birdeye service is unavailable or does not have getTokensMarketData method",
|
|
117
|
+
);
|
|
118
|
+
return {
|
|
119
|
+
values: {},
|
|
120
|
+
text: [
|
|
121
|
+
"birdeye_market_data:",
|
|
122
|
+
" status: unavailable",
|
|
123
|
+
" reason: missing getTokensMarketData",
|
|
124
|
+
].join("\n"),
|
|
125
|
+
data: {},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// FIXME: cache (how fresh does this have to be? 5 mins? 1 min?)
|
|
130
|
+
// get data
|
|
131
|
+
const ps = [birdeyeService.getTokensMarketData("solana", CAs)];
|
|
132
|
+
if (
|
|
133
|
+
solanaService &&
|
|
134
|
+
typeof solanaService.getTokensSymbols === "function"
|
|
135
|
+
) {
|
|
136
|
+
ps.push(solanaService.getTokensSymbols(CAs));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const results = await Promise.all(ps);
|
|
140
|
+
|
|
141
|
+
const result = results[0]; // birdeye Results
|
|
142
|
+
const rows = [];
|
|
143
|
+
|
|
144
|
+
// FIXME: Market cap column is currently not populated from Birdeye API response
|
|
145
|
+
// Need to calculate or fetch market cap data separately
|
|
146
|
+
for (const ca of CAs) {
|
|
147
|
+
// Check if result[ca] exists before accessing it
|
|
148
|
+
if (!result[ca]) {
|
|
149
|
+
rows.push({
|
|
150
|
+
chain: "solana",
|
|
151
|
+
address: ca,
|
|
152
|
+
symbol: "unknown",
|
|
153
|
+
priceUsd: "unknown",
|
|
154
|
+
marketCapUsd: "unknown",
|
|
155
|
+
change24hPct: "unknown",
|
|
156
|
+
liquidityUsd: "unknown",
|
|
157
|
+
});
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const t = result[ca];
|
|
162
|
+
t.symbol =
|
|
163
|
+
solanaService && results[1]
|
|
164
|
+
? results[1][ca]
|
|
165
|
+
: (hardcodedSolanaCA2SymbolMap[ca] ?? "(Not available)");
|
|
166
|
+
// unwrap symbols
|
|
167
|
+
if (t.symbol === "WBTC") t.symbol = "BTC";
|
|
168
|
+
if (t.symbol === "WETH") t.symbol = "ETH";
|
|
169
|
+
//console.log('t', t)
|
|
170
|
+
rows.push({
|
|
171
|
+
chain: "solana",
|
|
172
|
+
address: ca,
|
|
173
|
+
symbol: t.symbol,
|
|
174
|
+
priceUsd: t.priceUsd.toFixed(4),
|
|
175
|
+
marketCapUsd: "unknown",
|
|
176
|
+
change24hPct: t.priceChange24h.toFixed(2),
|
|
177
|
+
liquidityUsd: t.liquidity.toFixed(2),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
//console.log('BIRDEYE_CRYPTOCURRENCY_MARKET_DATA - birdye market data text', latestTxt)
|
|
182
|
+
|
|
183
|
+
const boundedRows = rows.slice(0, MARKET_ROW_LIMIT);
|
|
184
|
+
const data = {
|
|
185
|
+
tokens: Object.fromEntries(
|
|
186
|
+
Object.entries(results[0] ?? {}).slice(0, MARKET_ROW_LIMIT),
|
|
187
|
+
),
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const values = {};
|
|
191
|
+
|
|
192
|
+
// Combine all text sections
|
|
193
|
+
const text = [
|
|
194
|
+
"birdeye_market_data:",
|
|
195
|
+
" status: ok",
|
|
196
|
+
formatJsonTable(" tokens", boundedRows, [
|
|
197
|
+
"chain",
|
|
198
|
+
"address",
|
|
199
|
+
"symbol",
|
|
200
|
+
"priceUsd",
|
|
201
|
+
"marketCapUsd",
|
|
202
|
+
"change24hPct",
|
|
203
|
+
"liquidityUsd",
|
|
204
|
+
]),
|
|
205
|
+
].join("\n");
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
data,
|
|
209
|
+
values,
|
|
210
|
+
text,
|
|
211
|
+
};
|
|
212
|
+
} catch (err) {
|
|
213
|
+
runtime.logger?.error(
|
|
214
|
+
`Error fetching Birdeye market data: ${err instanceof Error ? err.message : String(err)}`,
|
|
215
|
+
);
|
|
216
|
+
return {
|
|
217
|
+
values: {},
|
|
218
|
+
text: [
|
|
219
|
+
"birdeye_market_data:",
|
|
220
|
+
" status: error",
|
|
221
|
+
` reason: ${formatJsonScalar(err instanceof Error ? err.message : String(err))}`,
|
|
222
|
+
].join("\n"),
|
|
223
|
+
data: {},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { IAgentRuntime, Memory, State } from "@elizaos/core";
|
|
2
|
+
import { describe, expect, it, vi } from "vitest";
|
|
3
|
+
import type { WalletPortfolioResponse } from "../types/api/wallet";
|
|
4
|
+
import {
|
|
5
|
+
createBirdeyePortfolioProvider,
|
|
6
|
+
formatPortfolio,
|
|
7
|
+
} from "./portfolio-factory";
|
|
8
|
+
|
|
9
|
+
const WALLET = "So11111111111111111111111111111111111111112";
|
|
10
|
+
|
|
11
|
+
function createRuntime(service: unknown): IAgentRuntime {
|
|
12
|
+
const runtime = {
|
|
13
|
+
getSetting: vi.fn((key: string) => {
|
|
14
|
+
if (key === "BIRDEYE_WALLET_ADDR") return WALLET;
|
|
15
|
+
if (key === "BIRDEYE_CHAIN") return "solana";
|
|
16
|
+
return undefined;
|
|
17
|
+
}),
|
|
18
|
+
getService: vi.fn(() => service),
|
|
19
|
+
logger: {
|
|
20
|
+
error: vi.fn(),
|
|
21
|
+
warn: vi.fn(),
|
|
22
|
+
log: vi.fn(),
|
|
23
|
+
debug: vi.fn(),
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return runtime as IAgentRuntime;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe("Birdeye portfolio provider factory", () => {
|
|
31
|
+
it("creates a portfolio provider that fetches holdings and renders JSON", async () => {
|
|
32
|
+
const service = {
|
|
33
|
+
fetchWalletTokenList: vi.fn(async () => ({
|
|
34
|
+
wallet: WALLET,
|
|
35
|
+
totalUsd: 250.5,
|
|
36
|
+
items: [
|
|
37
|
+
{
|
|
38
|
+
symbol: "SOL",
|
|
39
|
+
address: WALLET,
|
|
40
|
+
uiAmount: 1.23456,
|
|
41
|
+
priceUsd: 200.123456,
|
|
42
|
+
valueUsd: 247.11,
|
|
43
|
+
chainId: "solana",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
})),
|
|
47
|
+
};
|
|
48
|
+
const provider = createBirdeyePortfolioProvider({
|
|
49
|
+
name: "TEST_PORTFOLIO",
|
|
50
|
+
description: "Test portfolio",
|
|
51
|
+
descriptionCompressed: "test birdeye portfolio",
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const result = await provider.get(
|
|
55
|
+
createRuntime(service),
|
|
56
|
+
{} as Memory,
|
|
57
|
+
{} as State,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
expect(service.fetchWalletTokenList).toHaveBeenCalledWith(
|
|
61
|
+
"solana",
|
|
62
|
+
WALLET,
|
|
63
|
+
{ notOlderThan: 30000 },
|
|
64
|
+
);
|
|
65
|
+
expect(result.text).toContain("birdeye_wallet_portfolio:");
|
|
66
|
+
expect(result.text).toContain(
|
|
67
|
+
"holdings[1]{symbol,address,amount,priceUsd,valueUsd,chainId}:",
|
|
68
|
+
);
|
|
69
|
+
expect(result.text).toContain("SOL");
|
|
70
|
+
expect(result.text).not.toContain("This is your portfolio");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("creates a trade provider variant from the same factory", async () => {
|
|
74
|
+
const service = {
|
|
75
|
+
fetchWalletTokenList: vi.fn(async () => ({
|
|
76
|
+
wallet: WALLET,
|
|
77
|
+
totalUsd: 50,
|
|
78
|
+
items: [],
|
|
79
|
+
})),
|
|
80
|
+
fetchWalletTxList: vi.fn(async () => [
|
|
81
|
+
{
|
|
82
|
+
txHash: "tx-1",
|
|
83
|
+
mainAction: "swap",
|
|
84
|
+
status: true,
|
|
85
|
+
blockTime: "2026-05-05T12:00:00Z",
|
|
86
|
+
from: WALLET,
|
|
87
|
+
to: "market",
|
|
88
|
+
},
|
|
89
|
+
]),
|
|
90
|
+
};
|
|
91
|
+
const provider = createBirdeyePortfolioProvider({
|
|
92
|
+
name: "TEST_TRADES",
|
|
93
|
+
description: "Test trades",
|
|
94
|
+
descriptionCompressed: "test birdeye trades",
|
|
95
|
+
includeTrades: true,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const result = await provider.get(
|
|
99
|
+
createRuntime(service),
|
|
100
|
+
{} as Memory,
|
|
101
|
+
{} as State,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
expect(service.fetchWalletTokenList).toHaveBeenCalledTimes(1);
|
|
105
|
+
expect(service.fetchWalletTxList).toHaveBeenCalledWith("solana", WALLET, {
|
|
106
|
+
notOlderThan: 30000,
|
|
107
|
+
});
|
|
108
|
+
expect(result.data).toMatchObject({
|
|
109
|
+
portfolio: { totalUsd: 50 },
|
|
110
|
+
trades: [{ txHash: "tx-1" }],
|
|
111
|
+
});
|
|
112
|
+
expect(result.text).toContain("tradeCount: 1");
|
|
113
|
+
expect(result.text).toContain(
|
|
114
|
+
"trades[1]{txHash,action,status,blockTime,from,to}:",
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("formats legacy portfolio wrappers as JSON holdings", () => {
|
|
119
|
+
const legacy: WalletPortfolioResponse = {
|
|
120
|
+
success: true,
|
|
121
|
+
data: {
|
|
122
|
+
items: [
|
|
123
|
+
{
|
|
124
|
+
symbol: "ETH",
|
|
125
|
+
address: "0x0000000000000000000000000000000000000000",
|
|
126
|
+
uiAmount: 2,
|
|
127
|
+
priceUsd: 100,
|
|
128
|
+
valueUsd: 200,
|
|
129
|
+
chainId: "ethereum",
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
expect(formatPortfolio(legacy)).toContain(
|
|
135
|
+
"holdings[1]{symbol,address,amount,priceUsd,valueUsd,chainId}:",
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
});
|