@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
package/src/lp/types.ts
ADDED
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
import type {
|
|
3
|
+
IAgentRuntime,
|
|
4
|
+
ILpService,
|
|
5
|
+
LpPositionDetails,
|
|
6
|
+
PoolInfo,
|
|
7
|
+
Service,
|
|
8
|
+
TokenBalance,
|
|
9
|
+
TransactionResult,
|
|
10
|
+
} from "@elizaos/core";
|
|
11
|
+
import type { Keypair as SolanaKeypair } from "@solana/web3.js";
|
|
12
|
+
import type { Address, Hash } from "viem";
|
|
13
|
+
|
|
14
|
+
// Re-export types from core with modern syntax
|
|
15
|
+
export type {
|
|
16
|
+
ILpService,
|
|
17
|
+
LpPositionDetails,
|
|
18
|
+
PoolInfo,
|
|
19
|
+
TokenBalance,
|
|
20
|
+
TransactionResult,
|
|
21
|
+
} from "@elizaos/core";
|
|
22
|
+
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Chain & Network Configuration
|
|
25
|
+
// ============================================================================
|
|
26
|
+
|
|
27
|
+
export type ChainType = "solana" | "evm";
|
|
28
|
+
|
|
29
|
+
export type SolanaDex = "raydium" | "orca" | "meteora";
|
|
30
|
+
export type EvmDex = "uniswap" | "pancakeswap" | "aerodrome";
|
|
31
|
+
export type DexName = SolanaDex | EvmDex;
|
|
32
|
+
|
|
33
|
+
export interface RpcConfig {
|
|
34
|
+
/** Primary RPC URL */
|
|
35
|
+
url: string;
|
|
36
|
+
/** Fallback RPC URLs */
|
|
37
|
+
fallbacks?: string[];
|
|
38
|
+
/** RPC provider name for identification */
|
|
39
|
+
provider?: "alchemy" | "infura" | "quicknode" | "public" | "custom";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface SolanaConfig {
|
|
43
|
+
/** Solana RPC configuration */
|
|
44
|
+
rpc: RpcConfig;
|
|
45
|
+
/** Private key (base58 encoded) */
|
|
46
|
+
privateKey?: string;
|
|
47
|
+
/** Enabled DEXs on Solana */
|
|
48
|
+
enabledDexes: SolanaDex[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface EvmChainConfig {
|
|
52
|
+
/** Chain ID */
|
|
53
|
+
chainId: number;
|
|
54
|
+
/** Chain name for display */
|
|
55
|
+
name: string;
|
|
56
|
+
/** RPC configuration */
|
|
57
|
+
rpc: RpcConfig;
|
|
58
|
+
/** Enabled DEXs on this chain */
|
|
59
|
+
enabledDexes: EvmDex[];
|
|
60
|
+
/** Native currency symbol */
|
|
61
|
+
nativeCurrency: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface EvmConfig {
|
|
65
|
+
/** Private key (hex string with 0x prefix) */
|
|
66
|
+
privateKey?: string;
|
|
67
|
+
/** Chain configurations */
|
|
68
|
+
chains: Record<string, EvmChainConfig>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface LpManagerConfig {
|
|
72
|
+
/** Solana configuration (optional) */
|
|
73
|
+
solana?: SolanaConfig;
|
|
74
|
+
/** EVM configuration (optional) */
|
|
75
|
+
evm?: EvmConfig;
|
|
76
|
+
/** Default slippage in basis points */
|
|
77
|
+
defaultSlippageBps?: number;
|
|
78
|
+
/** Auto-rebalance settings */
|
|
79
|
+
autoRebalance?: {
|
|
80
|
+
enabled: boolean;
|
|
81
|
+
checkIntervalMs: number;
|
|
82
|
+
minGainThresholdPercent: number;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// EVM-Specific Types
|
|
88
|
+
// ============================================================================
|
|
89
|
+
|
|
90
|
+
export interface EvmWallet {
|
|
91
|
+
address: Address;
|
|
92
|
+
privateKey: `0x${string}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface EvmPoolInfo extends Omit<PoolInfo, "tokenA" | "tokenB"> {
|
|
96
|
+
/** Chain ID where the pool exists */
|
|
97
|
+
chainId: number;
|
|
98
|
+
/** Chain name */
|
|
99
|
+
chainName: string;
|
|
100
|
+
/** Pool contract address */
|
|
101
|
+
poolAddress: Address;
|
|
102
|
+
/** Token A info with EVM address */
|
|
103
|
+
tokenA: {
|
|
104
|
+
address: Address;
|
|
105
|
+
symbol?: string;
|
|
106
|
+
decimals: number;
|
|
107
|
+
reserve?: string;
|
|
108
|
+
};
|
|
109
|
+
/** Token B info with EVM address */
|
|
110
|
+
tokenB: {
|
|
111
|
+
address: Address;
|
|
112
|
+
symbol?: string;
|
|
113
|
+
decimals: number;
|
|
114
|
+
reserve?: string;
|
|
115
|
+
};
|
|
116
|
+
/** Fee tier (for Uniswap V3 style pools) */
|
|
117
|
+
feeTier?: number;
|
|
118
|
+
/** Tick spacing (for concentrated liquidity) */
|
|
119
|
+
tickSpacing?: number;
|
|
120
|
+
/** Current tick */
|
|
121
|
+
currentTick?: number;
|
|
122
|
+
/** Current sqrt price X96 */
|
|
123
|
+
sqrtPriceX96?: bigint;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface EvmPositionDetails
|
|
127
|
+
extends Omit<LpPositionDetails, "lpTokenBalance" | "underlyingTokens"> {
|
|
128
|
+
/** Chain ID */
|
|
129
|
+
chainId: number;
|
|
130
|
+
/** Position NFT token ID (for Uniswap V3 style) */
|
|
131
|
+
tokenId?: bigint;
|
|
132
|
+
/** Position owner address */
|
|
133
|
+
owner: Address;
|
|
134
|
+
/** Lower tick (concentrated liquidity) */
|
|
135
|
+
tickLower?: number;
|
|
136
|
+
/** Upper tick (concentrated liquidity) */
|
|
137
|
+
tickUpper?: number;
|
|
138
|
+
/** Liquidity amount */
|
|
139
|
+
liquidity?: bigint;
|
|
140
|
+
/** LP token balance with EVM address */
|
|
141
|
+
lpTokenBalance: {
|
|
142
|
+
address: Address;
|
|
143
|
+
balance: string;
|
|
144
|
+
decimals: number;
|
|
145
|
+
symbol?: string;
|
|
146
|
+
uiAmount?: number;
|
|
147
|
+
name?: string;
|
|
148
|
+
logoURI?: string;
|
|
149
|
+
};
|
|
150
|
+
/** Underlying tokens with EVM addresses */
|
|
151
|
+
underlyingTokens: Array<{
|
|
152
|
+
address: Address;
|
|
153
|
+
balance: string;
|
|
154
|
+
decimals: number;
|
|
155
|
+
symbol?: string;
|
|
156
|
+
uiAmount?: number;
|
|
157
|
+
name?: string;
|
|
158
|
+
logoURI?: string;
|
|
159
|
+
}>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface EvmAddLiquidityParams {
|
|
163
|
+
/** Wallet/signer */
|
|
164
|
+
wallet: EvmWallet;
|
|
165
|
+
/** Chain ID */
|
|
166
|
+
chainId: number;
|
|
167
|
+
/** Pool address */
|
|
168
|
+
poolAddress: Address;
|
|
169
|
+
/** Token A amount (in wei) */
|
|
170
|
+
tokenAAmount: bigint;
|
|
171
|
+
/** Token B amount (in wei) */
|
|
172
|
+
tokenBAmount?: bigint;
|
|
173
|
+
/** Slippage tolerance in bps */
|
|
174
|
+
slippageBps: number;
|
|
175
|
+
/** Lower tick for concentrated liquidity */
|
|
176
|
+
tickLower?: number;
|
|
177
|
+
/** Upper tick for concentrated liquidity */
|
|
178
|
+
tickUpper?: number;
|
|
179
|
+
/** Deadline timestamp */
|
|
180
|
+
deadline?: bigint;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface EvmRemoveLiquidityParams {
|
|
184
|
+
/** Wallet/signer */
|
|
185
|
+
wallet: EvmWallet;
|
|
186
|
+
/** Chain ID */
|
|
187
|
+
chainId: number;
|
|
188
|
+
/** Pool address */
|
|
189
|
+
poolAddress: Address;
|
|
190
|
+
/** Position token ID (for NFT positions) */
|
|
191
|
+
tokenId?: bigint;
|
|
192
|
+
/** LP token amount to remove (for standard pools) */
|
|
193
|
+
lpTokenAmount?: bigint;
|
|
194
|
+
/** Percentage to remove (0-100) */
|
|
195
|
+
percentageToRemove?: number;
|
|
196
|
+
/** Slippage tolerance in bps */
|
|
197
|
+
slippageBps: number;
|
|
198
|
+
/** Deadline timestamp */
|
|
199
|
+
deadline?: bigint;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export interface EvmTransactionResult extends TransactionResult {
|
|
203
|
+
/** Transaction hash */
|
|
204
|
+
hash?: Hash;
|
|
205
|
+
/** Chain ID */
|
|
206
|
+
chainId?: number;
|
|
207
|
+
/** Block number */
|
|
208
|
+
blockNumber?: bigint;
|
|
209
|
+
/** Gas used */
|
|
210
|
+
gasUsed?: bigint;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ============================================================================
|
|
214
|
+
// EVM LP Service Interface
|
|
215
|
+
// ============================================================================
|
|
216
|
+
|
|
217
|
+
export interface IEvmLpService extends Service {
|
|
218
|
+
/** Returns the DEX name */
|
|
219
|
+
getDexName(): EvmDex;
|
|
220
|
+
|
|
221
|
+
/** Returns supported chain IDs */
|
|
222
|
+
getSupportedChainIds(): number[];
|
|
223
|
+
|
|
224
|
+
/** Check if a chain is supported */
|
|
225
|
+
supportsChain(chainId: number): boolean;
|
|
226
|
+
|
|
227
|
+
/** Get pools on a specific chain */
|
|
228
|
+
getPools(
|
|
229
|
+
chainId: number,
|
|
230
|
+
tokenA?: Address,
|
|
231
|
+
tokenB?: Address,
|
|
232
|
+
feeTier?: number,
|
|
233
|
+
): Promise<EvmPoolInfo[]>;
|
|
234
|
+
|
|
235
|
+
/** Add liquidity to a pool */
|
|
236
|
+
addLiquidity(params: EvmAddLiquidityParams): Promise<EvmTransactionResult>;
|
|
237
|
+
|
|
238
|
+
/** Remove liquidity from a pool */
|
|
239
|
+
removeLiquidity(
|
|
240
|
+
params: EvmRemoveLiquidityParams,
|
|
241
|
+
): Promise<EvmTransactionResult>;
|
|
242
|
+
|
|
243
|
+
/** Get position details */
|
|
244
|
+
getPositionDetails(
|
|
245
|
+
chainId: number,
|
|
246
|
+
owner: Address,
|
|
247
|
+
poolAddress: Address,
|
|
248
|
+
tokenId?: bigint,
|
|
249
|
+
): Promise<EvmPositionDetails | null>;
|
|
250
|
+
|
|
251
|
+
/** Get all positions for an address */
|
|
252
|
+
getAllPositions(
|
|
253
|
+
chainId: number,
|
|
254
|
+
owner: Address,
|
|
255
|
+
): Promise<EvmPositionDetails[]>;
|
|
256
|
+
|
|
257
|
+
/** Get market data for pools */
|
|
258
|
+
getMarketData(
|
|
259
|
+
poolAddresses: Address[],
|
|
260
|
+
): Promise<Record<string, Partial<EvmPoolInfo>>>;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ============================================================================
|
|
264
|
+
// Supported Chains Configuration
|
|
265
|
+
// ============================================================================
|
|
266
|
+
|
|
267
|
+
export const SUPPORTED_EVM_CHAINS = {
|
|
268
|
+
// Ethereum Mainnet
|
|
269
|
+
ethereum: {
|
|
270
|
+
chainId: 1,
|
|
271
|
+
name: "Ethereum",
|
|
272
|
+
nativeCurrency: "ETH",
|
|
273
|
+
supportedDexes: ["uniswap"] as EvmDex[],
|
|
274
|
+
rpcEnvKeys: ["ETHEREUM_RPC_URL", "ETH_RPC_URL", "EVM_PROVIDER_MAINNET"],
|
|
275
|
+
},
|
|
276
|
+
// Base
|
|
277
|
+
base: {
|
|
278
|
+
chainId: 8453,
|
|
279
|
+
name: "Base",
|
|
280
|
+
nativeCurrency: "ETH",
|
|
281
|
+
supportedDexes: ["uniswap", "aerodrome"] as EvmDex[],
|
|
282
|
+
rpcEnvKeys: ["BASE_RPC_URL", "EVM_PROVIDER_BASE"],
|
|
283
|
+
},
|
|
284
|
+
// Arbitrum
|
|
285
|
+
arbitrum: {
|
|
286
|
+
chainId: 42161,
|
|
287
|
+
name: "Arbitrum One",
|
|
288
|
+
nativeCurrency: "ETH",
|
|
289
|
+
supportedDexes: ["uniswap", "pancakeswap"] as EvmDex[],
|
|
290
|
+
rpcEnvKeys: ["ARBITRUM_RPC_URL", "EVM_PROVIDER_ARBITRUM"],
|
|
291
|
+
},
|
|
292
|
+
// BSC
|
|
293
|
+
bsc: {
|
|
294
|
+
chainId: 56,
|
|
295
|
+
name: "BNB Smart Chain",
|
|
296
|
+
nativeCurrency: "BNB",
|
|
297
|
+
supportedDexes: ["pancakeswap"] as EvmDex[],
|
|
298
|
+
rpcEnvKeys: ["BSC_RPC_URL", "EVM_PROVIDER_BSC"],
|
|
299
|
+
},
|
|
300
|
+
// Polygon
|
|
301
|
+
polygon: {
|
|
302
|
+
chainId: 137,
|
|
303
|
+
name: "Polygon",
|
|
304
|
+
nativeCurrency: "MATIC",
|
|
305
|
+
supportedDexes: ["uniswap"] as EvmDex[],
|
|
306
|
+
rpcEnvKeys: ["POLYGON_RPC_URL", "EVM_PROVIDER_POLYGON"],
|
|
307
|
+
},
|
|
308
|
+
// Optimism
|
|
309
|
+
optimism: {
|
|
310
|
+
chainId: 10,
|
|
311
|
+
name: "Optimism",
|
|
312
|
+
nativeCurrency: "ETH",
|
|
313
|
+
supportedDexes: ["uniswap"] as EvmDex[],
|
|
314
|
+
rpcEnvKeys: ["OPTIMISM_RPC_URL", "EVM_PROVIDER_OPTIMISM"],
|
|
315
|
+
},
|
|
316
|
+
} as const;
|
|
317
|
+
|
|
318
|
+
export type SupportedEvmChain = keyof typeof SUPPORTED_EVM_CHAINS;
|
|
319
|
+
|
|
320
|
+
// Helper function to get chain config
|
|
321
|
+
export function getChainConfig(chainNameOrId: string | number) {
|
|
322
|
+
if (typeof chainNameOrId === "number") {
|
|
323
|
+
return Object.values(SUPPORTED_EVM_CHAINS).find(
|
|
324
|
+
(c) => c.chainId === chainNameOrId,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
return SUPPORTED_EVM_CHAINS[chainNameOrId as SupportedEvmChain];
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export type OptimizationOpportunity = {
|
|
331
|
+
sourcePosition?: LpPositionDetails;
|
|
332
|
+
sourcePool?: PoolInfo;
|
|
333
|
+
targetPool: PoolInfo;
|
|
334
|
+
estimatedNewYield: number;
|
|
335
|
+
currentYield?: number;
|
|
336
|
+
estimatedCostToMoveLamports?: string;
|
|
337
|
+
estimatedCostToMoveUsd?: number;
|
|
338
|
+
netGainPercent?: number;
|
|
339
|
+
reason?: string;
|
|
340
|
+
actions?: string[];
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export type UserLpProfile = {
|
|
344
|
+
userId: string;
|
|
345
|
+
vaultPublicKey: string;
|
|
346
|
+
encryptedSecretKey: string;
|
|
347
|
+
autoRebalanceConfig: {
|
|
348
|
+
enabled: boolean;
|
|
349
|
+
minGainThresholdPercent: number;
|
|
350
|
+
preferredDexes?: string[];
|
|
351
|
+
maxSlippageBps: number;
|
|
352
|
+
maxGasFeeLamports?: string;
|
|
353
|
+
cycleIntervalHours?: number;
|
|
354
|
+
};
|
|
355
|
+
trackedPositions?: TrackedLpPosition[];
|
|
356
|
+
version: number;
|
|
357
|
+
createdAt: string;
|
|
358
|
+
updatedAt: string;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
export interface TrackedLpPosition {
|
|
362
|
+
positionIdentifier: string;
|
|
363
|
+
dex: string;
|
|
364
|
+
poolAddress: string;
|
|
365
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
366
|
+
trackedAt: string;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export type TrackedLpPositionInput = Omit<TrackedLpPosition, "trackedAt">;
|
|
370
|
+
|
|
371
|
+
export interface AddLiquidityConfig {
|
|
372
|
+
userVault: SolanaKeypair;
|
|
373
|
+
dexName: string;
|
|
374
|
+
poolId: string;
|
|
375
|
+
tokenAAmountLamports: string;
|
|
376
|
+
tokenBAmountLamports?: string;
|
|
377
|
+
slippageBps: number;
|
|
378
|
+
tickLowerIndex?: number;
|
|
379
|
+
tickUpperIndex?: number;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export interface RemoveLiquidityConfig {
|
|
383
|
+
userVault: SolanaKeypair;
|
|
384
|
+
dexName: string;
|
|
385
|
+
poolId: string;
|
|
386
|
+
lpTokenAmountLamports: string;
|
|
387
|
+
slippageBps: number;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export type LpManagementSubaction =
|
|
391
|
+
| "onboard"
|
|
392
|
+
| "list_pools"
|
|
393
|
+
| "open"
|
|
394
|
+
| "close"
|
|
395
|
+
| "reposition"
|
|
396
|
+
| "list_positions"
|
|
397
|
+
| "get_position"
|
|
398
|
+
| "set_preferences";
|
|
399
|
+
|
|
400
|
+
export interface LpActionParams {
|
|
401
|
+
subaction?: LpManagementSubaction;
|
|
402
|
+
chain?: ChainType | string;
|
|
403
|
+
chainId?: number;
|
|
404
|
+
dex?: string;
|
|
405
|
+
pool?: string;
|
|
406
|
+
position?: string;
|
|
407
|
+
amount?:
|
|
408
|
+
| string
|
|
409
|
+
| number
|
|
410
|
+
| {
|
|
411
|
+
value?: string | number;
|
|
412
|
+
tokenA?: string | number;
|
|
413
|
+
tokenB?: string | number;
|
|
414
|
+
lpToken?: string | number;
|
|
415
|
+
percentage?: number;
|
|
416
|
+
};
|
|
417
|
+
amounts?: {
|
|
418
|
+
tokenA?: string | number;
|
|
419
|
+
tokenB?: string | number;
|
|
420
|
+
lpToken?: string | number;
|
|
421
|
+
};
|
|
422
|
+
range?: {
|
|
423
|
+
tickLower?: number;
|
|
424
|
+
tickUpper?: number;
|
|
425
|
+
tickLowerIndex?: number;
|
|
426
|
+
tickUpperIndex?: number;
|
|
427
|
+
priceLower?: number;
|
|
428
|
+
priceUpper?: number;
|
|
429
|
+
};
|
|
430
|
+
tokenA?: string;
|
|
431
|
+
tokenB?: string;
|
|
432
|
+
feeTier?: number;
|
|
433
|
+
slippageBps?: number;
|
|
434
|
+
intent?:
|
|
435
|
+
| "onboard_lp"
|
|
436
|
+
| "deposit_lp"
|
|
437
|
+
| "withdraw_lp"
|
|
438
|
+
| "show_lps"
|
|
439
|
+
| "set_lp_preferences"
|
|
440
|
+
| "create_concentrated_lp"
|
|
441
|
+
| "rebalance_concentrated_lp"
|
|
442
|
+
| "show_concentrated_lps";
|
|
443
|
+
userId?: string;
|
|
444
|
+
dexName?: string;
|
|
445
|
+
poolId?: string;
|
|
446
|
+
tokenAAmount?: string;
|
|
447
|
+
tokenBAmount?: string;
|
|
448
|
+
lpTokenAmount?: string;
|
|
449
|
+
percentage?: number;
|
|
450
|
+
autoRebalanceConfig?: Partial<UserLpProfile["autoRebalanceConfig"]>;
|
|
451
|
+
autoRebalanceEnabled?: boolean;
|
|
452
|
+
minGainThresholdPercent?: number;
|
|
453
|
+
maxSlippageBps?: number;
|
|
454
|
+
preferredDexes?: string[];
|
|
455
|
+
cycleIntervalHours?: number;
|
|
456
|
+
maxGasFeeLamports?: string;
|
|
457
|
+
tickLowerIndex?: number;
|
|
458
|
+
tickUpperIndex?: number;
|
|
459
|
+
// Concentrated liquidity specific params
|
|
460
|
+
priceLower?: number;
|
|
461
|
+
priceUpper?: number;
|
|
462
|
+
rangeWidthPercent?: number;
|
|
463
|
+
positionId?: string;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export interface IVaultService extends Service {
|
|
467
|
+
createVault(
|
|
468
|
+
userId: string,
|
|
469
|
+
): Promise<{ publicKey: string; secretKeyEncrypted: string }>;
|
|
470
|
+
getVaultKeypair(
|
|
471
|
+
userId: string,
|
|
472
|
+
encryptedSecretKey: string,
|
|
473
|
+
): Promise<SolanaKeypair>;
|
|
474
|
+
getVaultPublicKey(userId: string): Promise<string | null>;
|
|
475
|
+
getBalances(publicKey: string): Promise<TokenBalance[]>;
|
|
476
|
+
exportPrivateKey(
|
|
477
|
+
userId: string,
|
|
478
|
+
encryptedSecretKey: string,
|
|
479
|
+
confirmationToken: string,
|
|
480
|
+
): Promise<string>;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export interface IUserLpProfileService extends Service {
|
|
484
|
+
ensureProfile(
|
|
485
|
+
userId: string,
|
|
486
|
+
vaultPublicKey: string,
|
|
487
|
+
encryptedSecretKey: string,
|
|
488
|
+
initialConfig?: Partial<UserLpProfile["autoRebalanceConfig"]>,
|
|
489
|
+
): Promise<UserLpProfile>;
|
|
490
|
+
getProfile(userId: string): Promise<UserLpProfile | null>;
|
|
491
|
+
updateProfile(
|
|
492
|
+
userId: string,
|
|
493
|
+
updates: Partial<Omit<UserLpProfile, "userId">>,
|
|
494
|
+
): Promise<UserLpProfile>;
|
|
495
|
+
addTrackedPosition(
|
|
496
|
+
userId: string,
|
|
497
|
+
position: TrackedLpPositionInput,
|
|
498
|
+
): Promise<UserLpProfile>;
|
|
499
|
+
removeTrackedPosition(
|
|
500
|
+
userId: string,
|
|
501
|
+
positionIdentifier: string,
|
|
502
|
+
): Promise<UserLpProfile>;
|
|
503
|
+
getTrackedPositions(userId: string): Promise<TrackedLpPosition[]>;
|
|
504
|
+
getAllProfilesWithAutoRebalanceEnabled(): Promise<UserLpProfile[]>;
|
|
505
|
+
start(runtime?: IAgentRuntime): Promise<void>;
|
|
506
|
+
stop(runtime?: IAgentRuntime): Promise<void>;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
export interface IDexInteractionService extends Service {
|
|
510
|
+
registerDexService(dexService: ILpService): void;
|
|
511
|
+
getPools(
|
|
512
|
+
dexName?: string,
|
|
513
|
+
tokenAMint?: string,
|
|
514
|
+
tokenBMint?: string,
|
|
515
|
+
): Promise<PoolInfo[]>;
|
|
516
|
+
addLiquidity(config: AddLiquidityConfig): Promise<TransactionResult>;
|
|
517
|
+
removeLiquidity(config: RemoveLiquidityConfig): Promise<TransactionResult>;
|
|
518
|
+
getLpPosition(
|
|
519
|
+
userId: string,
|
|
520
|
+
poolIdOrPositionIdentifier: string,
|
|
521
|
+
dexName: string,
|
|
522
|
+
): Promise<LpPositionDetails | null>;
|
|
523
|
+
getAllUserLpPositions(userId: string): Promise<LpPositionDetails[]>;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export interface IYieldOptimizationService extends Service {
|
|
527
|
+
fetchAllPoolData(): Promise<PoolInfo[]>;
|
|
528
|
+
findBestYieldOpportunities(
|
|
529
|
+
userId: string,
|
|
530
|
+
currentPositions: LpPositionDetails[],
|
|
531
|
+
idleAssets: TokenBalance[],
|
|
532
|
+
): Promise<OptimizationOpportunity[]>;
|
|
533
|
+
calculateRebalanceCost(
|
|
534
|
+
fromPosition: LpPositionDetails | null,
|
|
535
|
+
toPool: PoolInfo,
|
|
536
|
+
solPriceUsd: number,
|
|
537
|
+
amountToMoveLamports?: string,
|
|
538
|
+
underlyingTokensToMove?: TokenBalance[],
|
|
539
|
+
): Promise<{
|
|
540
|
+
costSolLamports: string;
|
|
541
|
+
costUsd?: number;
|
|
542
|
+
steps: string[];
|
|
543
|
+
error?: string;
|
|
544
|
+
}>;
|
|
545
|
+
findBestYield(
|
|
546
|
+
userId: string,
|
|
547
|
+
currentTokenA: string,
|
|
548
|
+
currentTokenB: string,
|
|
549
|
+
): Promise<OptimizationOpportunity[]>;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Concentrated Liquidity Types
|
|
553
|
+
export interface IConcentratedPosition extends LpPositionDetails {
|
|
554
|
+
priceLower: number;
|
|
555
|
+
priceUpper: number;
|
|
556
|
+
currentPrice: number;
|
|
557
|
+
inRange: boolean;
|
|
558
|
+
liquidityUtilization: number;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export interface IRangeParams {
|
|
562
|
+
poolAddress: string;
|
|
563
|
+
baseAmount?: number;
|
|
564
|
+
quoteAmount?: number;
|
|
565
|
+
priceLower?: number;
|
|
566
|
+
priceUpper?: number;
|
|
567
|
+
rangeWidthPercent?: number;
|
|
568
|
+
targetUtilization?: number;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export interface IConcentratedLiquidityService extends Service {
|
|
572
|
+
createConcentratedPosition(
|
|
573
|
+
userId: string,
|
|
574
|
+
params: IRangeParams,
|
|
575
|
+
): Promise<IConcentratedPosition>;
|
|
576
|
+
getConcentratedPositions(userId: string): Promise<IConcentratedPosition[]>;
|
|
577
|
+
rebalanceConcentratedPosition(
|
|
578
|
+
userId: string,
|
|
579
|
+
positionId: string,
|
|
580
|
+
newRangeParams?: Partial<IRangeParams>,
|
|
581
|
+
): Promise<IConcentratedPosition>;
|
|
582
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
|
|
2
|
+
import { type IAgentRuntime, logger } from "@elizaos/core";
|
|
3
|
+
import { Connection, clusterApiUrl, Keypair, PublicKey } from "@solana/web3.js";
|
|
4
|
+
import bs58 from "bs58";
|
|
5
|
+
|
|
6
|
+
const DEFAULT_ENDPOINT = clusterApiUrl("mainnet-beta");
|
|
7
|
+
const DEFAULT_COMMITMENT = "confirmed";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Gets a Solana RPC connection configured from runtime settings
|
|
11
|
+
*/
|
|
12
|
+
export function getConnection(runtime: IAgentRuntime): Connection {
|
|
13
|
+
const rpcUrl =
|
|
14
|
+
runtime.getSetting("SOLANA_RPC_URL") ||
|
|
15
|
+
runtime.getSetting("RPC_URL") ||
|
|
16
|
+
DEFAULT_ENDPOINT;
|
|
17
|
+
const commitmentRaw =
|
|
18
|
+
runtime.getSetting("SOLANA_COMMITMENT") || DEFAULT_COMMITMENT;
|
|
19
|
+
const commitment =
|
|
20
|
+
typeof commitmentRaw === "string" ? commitmentRaw : DEFAULT_COMMITMENT;
|
|
21
|
+
|
|
22
|
+
return new Connection(
|
|
23
|
+
rpcUrl as string,
|
|
24
|
+
commitment as "confirmed" | "finalized" | "processed",
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function getWalletPublicKey(runtime: IAgentRuntime): string | null {
|
|
29
|
+
const pubKey = runtime.getSetting("SOLANA_PUBLIC_KEY");
|
|
30
|
+
return pubKey && typeof pubKey === "string" ? pubKey : null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getWalletPrivateKey(runtime: IAgentRuntime): string | null {
|
|
34
|
+
const privKey = runtime.getSetting("SOLANA_PRIVATE_KEY");
|
|
35
|
+
return privKey && typeof privKey === "string" ? privKey : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Wallet result containing either a signer or public address
|
|
40
|
+
*/
|
|
41
|
+
export interface WalletResult {
|
|
42
|
+
signer?: Keypair;
|
|
43
|
+
address: PublicKey;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Loads a Solana wallet from runtime settings
|
|
48
|
+
* @param runtime The agent runtime
|
|
49
|
+
* @param requirePrivateKey Whether to require a full keypair (true) or just public key (false)
|
|
50
|
+
* @returns WalletResult containing either keypair or public key
|
|
51
|
+
*/
|
|
52
|
+
export async function loadWallet(
|
|
53
|
+
runtime: IAgentRuntime,
|
|
54
|
+
requirePrivateKey: boolean = true,
|
|
55
|
+
): Promise<WalletResult> {
|
|
56
|
+
if (requirePrivateKey) {
|
|
57
|
+
const privateKeyString = getWalletPrivateKey(runtime);
|
|
58
|
+
|
|
59
|
+
if (!privateKeyString) {
|
|
60
|
+
throw new Error("SOLANA_PRIVATE_KEY not found in settings");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
// First try base58
|
|
65
|
+
const secretKey = bs58.decode(privateKeyString);
|
|
66
|
+
const signer = Keypair.fromSecretKey(secretKey);
|
|
67
|
+
return { signer, address: signer.publicKey };
|
|
68
|
+
} catch (_e) {
|
|
69
|
+
logger.debug("Error decoding base58 private key, trying base64...");
|
|
70
|
+
try {
|
|
71
|
+
// Then try base64
|
|
72
|
+
const secretKey = Uint8Array.from(
|
|
73
|
+
Buffer.from(privateKeyString, "base64"),
|
|
74
|
+
);
|
|
75
|
+
const signer = Keypair.fromSecretKey(secretKey);
|
|
76
|
+
return { signer, address: signer.publicKey };
|
|
77
|
+
} catch (e2) {
|
|
78
|
+
logger.error("Error decoding private key:", e2);
|
|
79
|
+
throw new Error(
|
|
80
|
+
"Invalid private key format - must be base58 or base64 encoded",
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
// Check if we have a private key we can derive address from
|
|
86
|
+
const privateKeyString = getWalletPrivateKey(runtime);
|
|
87
|
+
if (privateKeyString) {
|
|
88
|
+
try {
|
|
89
|
+
const secretKey = bs58.decode(privateKeyString);
|
|
90
|
+
const keypair = Keypair.fromSecretKey(secretKey);
|
|
91
|
+
return { address: keypair.publicKey };
|
|
92
|
+
} catch {
|
|
93
|
+
// Fall through to public key check
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const publicKeyString = getWalletPublicKey(runtime);
|
|
98
|
+
if (!publicKeyString) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
"SOLANA_PUBLIC_KEY or SOLANA_PRIVATE_KEY not found in settings",
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { address: new PublicKey(publicKeyString) };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Sends a transaction with proper error handling and confirmation
|
|
110
|
+
*/
|
|
111
|
+
export async function sendTransaction(
|
|
112
|
+
connection: Connection,
|
|
113
|
+
instructions: import("@solana/web3.js").TransactionInstruction[],
|
|
114
|
+
signer: Keypair,
|
|
115
|
+
): Promise<string> {
|
|
116
|
+
const { Transaction } = await import("@solana/web3.js");
|
|
117
|
+
|
|
118
|
+
const transaction = new Transaction();
|
|
119
|
+
transaction.add(...instructions);
|
|
120
|
+
|
|
121
|
+
const { blockhash, lastValidBlockHeight } =
|
|
122
|
+
await connection.getLatestBlockhash();
|
|
123
|
+
transaction.recentBlockhash = blockhash;
|
|
124
|
+
transaction.feePayer = signer.publicKey;
|
|
125
|
+
|
|
126
|
+
transaction.sign(signer);
|
|
127
|
+
|
|
128
|
+
const signature = await connection.sendRawTransaction(
|
|
129
|
+
transaction.serialize(),
|
|
130
|
+
{
|
|
131
|
+
skipPreflight: false,
|
|
132
|
+
preflightCommitment: "confirmed",
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
await connection.confirmTransaction({
|
|
137
|
+
blockhash,
|
|
138
|
+
lastValidBlockHeight,
|
|
139
|
+
signature,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return signature;
|
|
143
|
+
}
|