mantle-agent-kit-sdk 1.0.2 → 1.0.4

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/dist/index.js CHANGED
@@ -1,20 +1,53 @@
1
- import { parseEther, encodeFunctionData, createWalletClient, http, publicActions, erc20Abi } from 'viem';
1
+ import { parseUnits, parseEther, encodeFunctionData, getAddress, parseAbiItem, createWalletClient, http, publicActions, erc20Abi as erc20Abi$1 } from 'viem';
2
2
  import { privateKeyToAccount } from 'viem/accounts';
3
3
  import { mantle, mantleSepoliaTestnet } from 'viem/chains';
4
4
  import { getTransactionReceipt } from 'viem/actions';
5
5
  import axios6 from 'axios';
6
6
  import CryptoJS from 'crypto-js';
7
+ import { erc7811Actions } from 'viem/experimental';
7
8
 
8
9
  var __defProp = Object.defineProperty;
9
10
  var __export = (target, all) => {
10
11
  for (var name in all)
11
12
  __defProp(target, name, { get: all[name], enumerable: true });
12
13
  };
13
- var sendTransaction = async (agent, to, amount) => {
14
- const hash = await agent.client.sendTransaction({
15
- to,
16
- value: parseEther(amount)
17
- });
14
+ var erc20Abi = [
15
+ {
16
+ name: "transfer",
17
+ type: "function",
18
+ inputs: [
19
+ { name: "to", type: "address" },
20
+ { name: "amount", type: "uint256" }
21
+ ],
22
+ outputs: [{ type: "bool" }]
23
+ },
24
+ {
25
+ name: "decimals",
26
+ type: "function",
27
+ inputs: [],
28
+ outputs: [{ type: "uint8" }]
29
+ }
30
+ ];
31
+ var sendTransaction = async (agent, to, amount, tokenAddress) => {
32
+ let hash;
33
+ if (tokenAddress) {
34
+ const decimals = await agent.client.readContract({
35
+ address: tokenAddress,
36
+ abi: erc20Abi,
37
+ functionName: "decimals"
38
+ });
39
+ hash = await agent.client.writeContract({
40
+ address: tokenAddress,
41
+ abi: erc20Abi,
42
+ functionName: "transfer",
43
+ args: [to, parseUnits(amount, decimals)]
44
+ });
45
+ } else {
46
+ hash = await agent.client.sendTransaction({
47
+ to,
48
+ value: parseEther(amount)
49
+ });
50
+ }
18
51
  const receipt = await getTransactionReceipt(agent.client, {
19
52
  hash
20
53
  });
@@ -24,7 +57,7 @@ async function checkAllowance(agent, tokenAddress, ownerAddress, spenderAddress)
24
57
  try {
25
58
  const allowance = await agent.client.readContract({
26
59
  address: tokenAddress,
27
- abi: erc20Abi,
60
+ abi: erc20Abi$1,
28
61
  functionName: "allowance",
29
62
  args: [ownerAddress, spenderAddress]
30
63
  });
@@ -188,9 +221,85 @@ async function getSwapTransaction(fromTokenAddress, toTokenAddress, amount, user
188
221
  throw error;
189
222
  }
190
223
  }
224
+ var DEMO_TX_HASH = "0xdemo000000000000000000000000000000000000000000000000000000000001";
225
+ function createMockSwapResponse(protocol, inputAmount) {
226
+ return {
227
+ txHash: DEMO_TX_HASH,
228
+ amountOut: inputAmount,
229
+ demo: true,
230
+ message: `[DEMO] ${protocol} swap simulated`
231
+ };
232
+ }
233
+ function createMockQuoteResponse(protocol, inputAmount) {
234
+ return {
235
+ estimatedAmount: inputAmount,
236
+ demo: true,
237
+ message: `[DEMO] ${protocol} quote simulated`
238
+ };
239
+ }
240
+ function createMockLendleResponse(action, amount) {
241
+ return {
242
+ txHash: DEMO_TX_HASH,
243
+ amount,
244
+ demo: true,
245
+ message: `[DEMO] Lendle ${action} simulated`
246
+ };
247
+ }
248
+ function createMockTxHash() {
249
+ return DEMO_TX_HASH;
250
+ }
251
+ function createMock1inchSwapResponse(inputAmount) {
252
+ return {
253
+ txHash: DEMO_TX_HASH,
254
+ dstAmount: inputAmount,
255
+ demo: true,
256
+ message: "[DEMO] 1inch swap simulated"
257
+ };
258
+ }
259
+ function createMockOkxSwapResponse(inputAmount) {
260
+ return {
261
+ data: DEMO_TX_HASH,
262
+ demo: true,
263
+ message: "[DEMO] OKX swap simulated"
264
+ };
265
+ }
266
+ function createMockOpenOceanSwapResponse(inputAmount) {
267
+ return {
268
+ txHash: DEMO_TX_HASH,
269
+ outAmount: inputAmount,
270
+ demo: true,
271
+ message: "[DEMO] OpenOcean swap simulated"
272
+ };
273
+ }
274
+ function createMockUniswapSwapResponse(inputAmount) {
275
+ return {
276
+ txHash: DEMO_TX_HASH,
277
+ amountOut: inputAmount,
278
+ demo: true,
279
+ message: "[DEMO] Uniswap swap simulated"
280
+ };
281
+ }
282
+ function createMockSquidRoute(amount) {
283
+ return {
284
+ route: {
285
+ estimate: { toAmount: amount },
286
+ transactionRequest: {
287
+ targetAddress: "0x0000000000000000000000000000000000000000",
288
+ data: "0x",
289
+ value: "0",
290
+ gasLimit: "0"
291
+ }
292
+ },
293
+ demo: true,
294
+ message: "[DEMO] Squid route simulated"
295
+ };
296
+ }
191
297
 
192
298
  // src/tools/okx/swap.ts
193
299
  async function executeSwap(agent, fromTokenAddress, toTokenAddress, amount, slippagePercent) {
300
+ if (agent.demo) {
301
+ return createMockOkxSwapResponse();
302
+ }
194
303
  const chainIndex = agent.chain === "mainnet" ? "5000" : "5003";
195
304
  const walletAddress = agent.account.address;
196
305
  if (fromTokenAddress !== ETH_ADDRESS) {
@@ -324,13 +433,16 @@ async function getSwapData(fromToken, toToken, amount, userAddress, slippage, ch
324
433
 
325
434
  // src/tools/openocean/getQuote.ts
326
435
  async function getOpenOceanQuote(agent, fromToken, toToken, amount) {
436
+ if (agent.demo) {
437
+ return createMockQuoteResponse("OpenOcean", amount);
438
+ }
327
439
  return await getQuoteData(fromToken, toToken, amount, agent.chain);
328
440
  }
329
441
  async function checkAllowance2(agent, tokenAddress, ownerAddress, spenderAddress) {
330
442
  try {
331
443
  const allowance = await agent.client.readContract({
332
444
  address: tokenAddress,
333
- abi: erc20Abi,
445
+ abi: erc20Abi$1,
334
446
  functionName: "allowance",
335
447
  args: [ownerAddress, spenderAddress]
336
448
  });
@@ -353,9 +465,9 @@ async function approveToken2(agent, tokenAddress, spenderAddress, amount) {
353
465
  return { approved: true, txHash: null };
354
466
  }
355
467
  console.log("Insufficient allowance, approving tokens...");
356
- const { encodeFunctionData: encodeFunctionData8 } = await import('viem');
357
- const approveData = encodeFunctionData8({
358
- abi: erc20Abi,
468
+ const { encodeFunctionData: encodeFunctionData11 } = await import('viem');
469
+ const approveData = encodeFunctionData11({
470
+ abi: erc20Abi$1,
359
471
  functionName: "approve",
360
472
  args: [spenderAddress, BigInt(amount)]
361
473
  });
@@ -380,6 +492,12 @@ async function approveToken2(agent, tokenAddress, spenderAddress, amount) {
380
492
 
381
493
  // src/tools/openocean/swap.ts
382
494
  async function swapOnOpenOcean(agent, fromToken, toToken, amount, slippage = "1") {
495
+ if (agent.demo) {
496
+ return createMockOpenOceanSwapResponse(amount);
497
+ }
498
+ if (!agent.demo && agent.chain != "mainnet") {
499
+ throw new Error("Openocean swaps happen only on mainnet");
500
+ }
383
501
  const walletAddress = agent.account.address;
384
502
  if (fromToken.toLowerCase() !== NATIVE_TOKEN_ADDRESS.toLowerCase()) {
385
503
  await approveToken2(agent, fromToken, OPENOCEAN_EXCHANGE_PROXY, amount);
@@ -491,11 +609,17 @@ async function getSwapData2(fromToken, toToken, amount, userAddress, slippage, c
491
609
 
492
610
  // src/tools/oneinch/getQuote.ts
493
611
  async function get1inchQuote(agent, fromToken, toToken, amount) {
612
+ if (agent.demo) {
613
+ return createMockQuoteResponse("1inch", amount);
614
+ }
494
615
  return await getQuoteData2(fromToken, toToken, amount, agent.chain);
495
616
  }
496
617
 
497
618
  // src/tools/oneinch/swap.ts
498
619
  async function swapOn1inch(agent, fromToken, toToken, amount, slippage = "1") {
620
+ if (agent.demo) {
621
+ return createMock1inchSwapResponse(amount);
622
+ }
499
623
  const walletAddress = agent.account.address;
500
624
  if (fromToken.toLowerCase() !== NATIVE_TOKEN_ADDRESS2.toLowerCase()) {
501
625
  await approveToken2(agent, fromToken, ONEINCH_ROUTER_ADDRESS, amount);
@@ -662,11 +786,17 @@ function buildSwapCalldata(params, fee = DEFAULT_POOL_FEE) {
662
786
 
663
787
  // src/tools/uniswap/getQuote.ts
664
788
  async function getUniswapQuote(agent, fromToken, toToken, amount, fee = DEFAULT_POOL_FEE) {
789
+ if (agent.demo) {
790
+ return createMockQuoteResponse("Uniswap", amount);
791
+ }
665
792
  return await getUniswapQuoteData(agent, fromToken, toToken, amount, fee);
666
793
  }
667
794
 
668
795
  // src/tools/uniswap/swap.ts
669
796
  async function swapOnUniswap(agent, fromToken, toToken, amount, slippage = "0.5", fee = DEFAULT_POOL_FEE) {
797
+ if (agent.demo) {
798
+ return createMockUniswapSwapResponse(amount);
799
+ }
670
800
  const walletAddress = agent.account.address;
671
801
  const isNativeIn = fromToken.toLowerCase() === NATIVE_TOKEN_ADDRESS3.toLowerCase();
672
802
  const quote = await getUniswapQuoteData(agent, fromToken, toToken, amount, fee);
@@ -765,6 +895,9 @@ async function getRouteData(fromToken, toToken, fromChain, toChain, amount, from
765
895
 
766
896
  // src/tools/squid/crossChainSwap.ts
767
897
  async function crossChainSwapViaSquid(agent, fromToken, toToken, fromChain, toChain, amount, slippage = 1) {
898
+ if (agent.demo) {
899
+ return createMockTxHash();
900
+ }
768
901
  const routeData = await getRouteData(
769
902
  fromToken,
770
903
  toToken,
@@ -793,6 +926,9 @@ async function crossChainSwapViaSquid(agent, fromToken, toToken, fromChain, toCh
793
926
  return hash;
794
927
  }
795
928
  async function getSquidRoute(agent, fromToken, toToken, fromChain, toChain, amount, slippage = 1) {
929
+ if (agent.demo) {
930
+ return createMockSquidRoute(amount);
931
+ }
796
932
  return await getRouteData(
797
933
  fromToken,
798
934
  toToken,
@@ -811,8 +947,10 @@ __export(lendle_exports, {
811
947
  LENDING_POOL: () => LENDING_POOL,
812
948
  LENDING_POOL_ABI: () => LENDING_POOL_ABI,
813
949
  LENDING_POOL_ADDRESSES_PROVIDER: () => LENDING_POOL_ADDRESSES_PROVIDER,
950
+ LENDLE_SUPPORTED_ASSETS: () => LENDLE_SUPPORTED_ASSETS,
814
951
  ORACLE: () => ORACLE,
815
952
  PROTOCOL_DATA_PROVIDER: () => PROTOCOL_DATA_PROVIDER,
953
+ PROTOCOL_DATA_PROVIDER_ABI: () => PROTOCOL_DATA_PROVIDER_ABI,
816
954
  WMNT_ADDRESS: () => WMNT_ADDRESS2
817
955
  });
818
956
  var LENDING_POOL = {
@@ -927,11 +1065,73 @@ var LENDING_POOL_ABI = [
927
1065
  type: "function"
928
1066
  }
929
1067
  ];
1068
+ var PROTOCOL_DATA_PROVIDER_ABI = [
1069
+ {
1070
+ inputs: [],
1071
+ name: "getAllReservesTokens",
1072
+ outputs: [
1073
+ {
1074
+ components: [
1075
+ { name: "symbol", type: "string" },
1076
+ { name: "tokenAddress", type: "address" }
1077
+ ],
1078
+ name: "",
1079
+ type: "tuple[]"
1080
+ }
1081
+ ],
1082
+ stateMutability: "view",
1083
+ type: "function"
1084
+ },
1085
+ {
1086
+ inputs: [
1087
+ { name: "asset", type: "address" },
1088
+ { name: "user", type: "address" }
1089
+ ],
1090
+ name: "getUserReserveData",
1091
+ outputs: [
1092
+ { name: "currentATokenBalance", type: "uint256" },
1093
+ { name: "currentStableDebt", type: "uint256" },
1094
+ { name: "currentVariableDebt", type: "uint256" },
1095
+ { name: "principalStableDebt", type: "uint256" },
1096
+ { name: "scaledVariableDebt", type: "uint256" },
1097
+ { name: "stableBorrowRate", type: "uint256" },
1098
+ { name: "liquidityRate", type: "uint256" },
1099
+ { name: "stableRateLastUpdated", type: "uint40" },
1100
+ { name: "usageAsCollateralEnabled", type: "bool" }
1101
+ ],
1102
+ stateMutability: "view",
1103
+ type: "function"
1104
+ },
1105
+ {
1106
+ inputs: [{ name: "asset", type: "address" }],
1107
+ name: "getReserveTokensAddresses",
1108
+ outputs: [
1109
+ { name: "aTokenAddress", type: "address" },
1110
+ { name: "stableDebtTokenAddress", type: "address" },
1111
+ { name: "variableDebtTokenAddress", type: "address" }
1112
+ ],
1113
+ stateMutability: "view",
1114
+ type: "function"
1115
+ }
1116
+ ];
1117
+ var LENDLE_SUPPORTED_ASSETS = {
1118
+ mainnet: [
1119
+ { symbol: "WMNT", address: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8" },
1120
+ { symbol: "WETH", address: "0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111" },
1121
+ { symbol: "USDC", address: "0x09Bc4E0D10C81b3a3766c49F0f98a8aaa7adA8D2" },
1122
+ { symbol: "USDT", address: "0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE" },
1123
+ { symbol: "mETH", address: "0xcDA86A272531e8640cD7F1a92c01839911B90bb0" }
1124
+ ],
1125
+ testnet: []
1126
+ };
930
1127
 
931
1128
  // src/tools/lendle/supply.ts
932
1129
  async function lendleSupply(agent, tokenAddress, amount) {
933
1130
  const lendingPoolAddress = LENDING_POOL[agent.chain];
934
1131
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1132
+ if (agent.demo) {
1133
+ return createMockLendleResponse("supply", amount).txHash;
1134
+ }
935
1135
  throw new Error(
936
1136
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
937
1137
  );
@@ -958,6 +1158,9 @@ async function lendleSupply(agent, tokenAddress, amount) {
958
1158
  async function lendleWithdraw(agent, tokenAddress, amount, to) {
959
1159
  const lendingPoolAddress = LENDING_POOL[agent.chain];
960
1160
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1161
+ if (agent.demo) {
1162
+ return createMockLendleResponse("withdraw", amount).txHash;
1163
+ }
961
1164
  throw new Error(
962
1165
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
963
1166
  );
@@ -979,6 +1182,9 @@ async function lendleWithdraw(agent, tokenAddress, amount, to) {
979
1182
  async function lendleBorrow(agent, tokenAddress, amount, interestRateMode = INTEREST_RATE_MODE.VARIABLE, onBehalfOf) {
980
1183
  const lendingPoolAddress = LENDING_POOL[agent.chain];
981
1184
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1185
+ if (agent.demo) {
1186
+ return createMockLendleResponse("borrow", amount).txHash;
1187
+ }
982
1188
  throw new Error(
983
1189
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
984
1190
  );
@@ -1001,6 +1207,9 @@ async function lendleBorrow(agent, tokenAddress, amount, interestRateMode = INTE
1001
1207
  async function lendleRepay(agent, tokenAddress, amount, rateMode = INTEREST_RATE_MODE.VARIABLE, onBehalfOf) {
1002
1208
  const lendingPoolAddress = LENDING_POOL[agent.chain];
1003
1209
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1210
+ if (agent.demo) {
1211
+ return createMockLendleResponse("repay", amount).txHash;
1212
+ }
1004
1213
  throw new Error(
1005
1214
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
1006
1215
  );
@@ -1020,6 +1229,67 @@ async function lendleRepay(agent, tokenAddress, amount, rateMode = INTEREST_RATE
1020
1229
  await agent.client.waitForTransactionReceipt({ hash });
1021
1230
  return hash;
1022
1231
  }
1232
+ async function lendleGetPositions(agent, userAddress) {
1233
+ const dataProviderAddress = PROTOCOL_DATA_PROVIDER[agent.chain];
1234
+ const address = userAddress || agent.account.address;
1235
+ if (dataProviderAddress === "0x0000000000000000000000000000000000000000") {
1236
+ throw new Error(
1237
+ `Lendle ProtocolDataProvider not configured for ${agent.chain}. Only available on mainnet.`
1238
+ );
1239
+ }
1240
+ const supportedAssets = LENDLE_SUPPORTED_ASSETS[agent.chain];
1241
+ if (!supportedAssets || supportedAssets.length === 0) {
1242
+ throw new Error(`No supported assets configured for ${agent.chain}`);
1243
+ }
1244
+ const positions = [];
1245
+ let totalSupplied = 0n;
1246
+ let totalDebt = 0n;
1247
+ for (const asset of supportedAssets) {
1248
+ try {
1249
+ const assetAddress = getAddress(asset.address);
1250
+ const result = await agent.client.readContract({
1251
+ address: dataProviderAddress,
1252
+ abi: PROTOCOL_DATA_PROVIDER_ABI,
1253
+ functionName: "getUserReserveData",
1254
+ args: [assetAddress, address]
1255
+ });
1256
+ const [
1257
+ currentATokenBalance,
1258
+ currentStableDebt,
1259
+ currentVariableDebt,
1260
+ _principalStableDebt,
1261
+ _scaledVariableDebt,
1262
+ stableBorrowRate,
1263
+ liquidityRate,
1264
+ _stableRateLastUpdated,
1265
+ usageAsCollateralEnabled
1266
+ ] = result;
1267
+ if (currentATokenBalance > 0n || currentStableDebt > 0n || currentVariableDebt > 0n) {
1268
+ const assetTotalDebt = currentStableDebt + currentVariableDebt;
1269
+ positions.push({
1270
+ asset: assetAddress,
1271
+ symbol: asset.symbol,
1272
+ supplied: currentATokenBalance,
1273
+ stableDebt: currentStableDebt,
1274
+ variableDebt: currentVariableDebt,
1275
+ totalDebt: assetTotalDebt,
1276
+ liquidityRate,
1277
+ stableBorrowRate,
1278
+ usageAsCollateralEnabled
1279
+ });
1280
+ totalSupplied += currentATokenBalance;
1281
+ totalDebt += assetTotalDebt;
1282
+ }
1283
+ } catch (error) {
1284
+ console.warn(`Failed to get position for ${asset.symbol}:`, error);
1285
+ }
1286
+ }
1287
+ return {
1288
+ positions,
1289
+ totalSupplied,
1290
+ totalDebt
1291
+ };
1292
+ }
1023
1293
 
1024
1294
  // src/constants/agni/index.ts
1025
1295
  var agni_exports = {};
@@ -1081,6 +1351,9 @@ var FEE_TIERS2 = {
1081
1351
  async function agniSwap(agent, tokenIn, tokenOut, amountIn, slippagePercent = 0.5, feeTier = FEE_TIERS2.MEDIUM) {
1082
1352
  const swapRouterAddress = SWAP_ROUTER[agent.chain];
1083
1353
  if (swapRouterAddress === "0x0000000000000000000000000000000000000000") {
1354
+ if (agent.demo) {
1355
+ return createMockSwapResponse("Agni", amountIn).txHash;
1356
+ }
1084
1357
  throw new Error(`Agni SwapRouter not available on ${agent.chain}`);
1085
1358
  }
1086
1359
  const amountInBigInt = BigInt(amountIn);
@@ -1153,6 +1426,9 @@ var LB_ROUTER_ABI = [
1153
1426
  async function merchantMoeSwap(agent, tokenIn, tokenOut, amountIn, slippagePercent = 0.5) {
1154
1427
  const routerAddress = LB_ROUTER[agent.chain];
1155
1428
  if (routerAddress === "0x0000000000000000000000000000000000000000") {
1429
+ if (agent.demo) {
1430
+ return createMockSwapResponse("MerchantMoe", amountIn).txHash;
1431
+ }
1156
1432
  throw new Error(`Merchant Moe LB Router not available on ${agent.chain}`);
1157
1433
  }
1158
1434
  const amountInBigInt = BigInt(amountIn);
@@ -1176,15 +1452,742 @@ async function merchantMoeSwap(agent, tokenIn, tokenOut, amountIn, slippagePerce
1176
1452
  // src/constants/meth/index.ts
1177
1453
  var meth_exports = {};
1178
1454
  __export(meth_exports, {
1179
- METH_TOKEN: () => METH_TOKEN
1455
+ METH_ABI: () => METH_ABI,
1456
+ METH_TOKEN: () => METH_TOKEN,
1457
+ NATIVE_MNT_ADDRESS: () => NATIVE_MNT_ADDRESS,
1458
+ WETH_TOKEN: () => WETH_TOKEN,
1459
+ WMNT_TOKEN: () => WMNT_TOKEN
1180
1460
  });
1181
1461
  var METH_TOKEN = {
1182
1462
  mainnet: "0xcDA86A272531e8640cD7F1a92c01839911B90bb0",
1183
1463
  testnet: "0x0000000000000000000000000000000000000000"
1184
1464
  };
1465
+ var WETH_TOKEN = {
1466
+ mainnet: "0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111",
1467
+ testnet: "0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111"
1468
+ };
1469
+ var WMNT_TOKEN = {
1470
+ mainnet: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8",
1471
+ testnet: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8"
1472
+ };
1473
+ var NATIVE_MNT_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
1474
+ var METH_ABI = [
1475
+ {
1476
+ inputs: [{ name: "account", type: "address" }],
1477
+ name: "balanceOf",
1478
+ outputs: [{ name: "", type: "uint256" }],
1479
+ stateMutability: "view",
1480
+ type: "function"
1481
+ },
1482
+ {
1483
+ inputs: [],
1484
+ name: "totalSupply",
1485
+ outputs: [{ name: "", type: "uint256" }],
1486
+ stateMutability: "view",
1487
+ type: "function"
1488
+ },
1489
+ {
1490
+ inputs: [],
1491
+ name: "decimals",
1492
+ outputs: [{ name: "", type: "uint8" }],
1493
+ stateMutability: "view",
1494
+ type: "function"
1495
+ },
1496
+ {
1497
+ inputs: [],
1498
+ name: "symbol",
1499
+ outputs: [{ name: "", type: "string" }],
1500
+ stateMutability: "view",
1501
+ type: "function"
1502
+ },
1503
+ {
1504
+ inputs: [
1505
+ { name: "spender", type: "address" },
1506
+ { name: "amount", type: "uint256" }
1507
+ ],
1508
+ name: "approve",
1509
+ outputs: [{ name: "", type: "bool" }],
1510
+ stateMutability: "nonpayable",
1511
+ type: "function"
1512
+ },
1513
+ {
1514
+ inputs: [
1515
+ { name: "owner", type: "address" },
1516
+ { name: "spender", type: "address" }
1517
+ ],
1518
+ name: "allowance",
1519
+ outputs: [{ name: "", type: "uint256" }],
1520
+ stateMutability: "view",
1521
+ type: "function"
1522
+ }
1523
+ ];
1524
+ async function methGetPosition(agent, userAddress) {
1525
+ const methTokenAddress = METH_TOKEN[agent.chain];
1526
+ const wethTokenAddress = WETH_TOKEN[agent.chain];
1527
+ const wmntTokenAddress = WMNT_TOKEN[agent.chain];
1528
+ const address = userAddress || agent.account.address;
1529
+ if (methTokenAddress === "0x0000000000000000000000000000000000000000") {
1530
+ throw new Error(
1531
+ `mETH not available on ${agent.chain}. Only available on mainnet.`
1532
+ );
1533
+ }
1534
+ const methBalance = await agent.client.readContract({
1535
+ address: methTokenAddress,
1536
+ abi: METH_ABI,
1537
+ functionName: "balanceOf",
1538
+ args: [address]
1539
+ });
1540
+ let wethBalance = 0n;
1541
+ try {
1542
+ wethBalance = await agent.client.readContract({
1543
+ address: wethTokenAddress,
1544
+ abi: METH_ABI,
1545
+ // Same ERC20 ABI works for WETH
1546
+ functionName: "balanceOf",
1547
+ args: [address]
1548
+ });
1549
+ } catch {
1550
+ }
1551
+ let wmntBalance = 0n;
1552
+ try {
1553
+ wmntBalance = await agent.client.readContract({
1554
+ address: wmntTokenAddress,
1555
+ abi: METH_ABI,
1556
+ // Same ERC20 ABI works for WMNT
1557
+ functionName: "balanceOf",
1558
+ args: [address]
1559
+ });
1560
+ } catch {
1561
+ }
1562
+ return {
1563
+ methBalance,
1564
+ wethBalance,
1565
+ wmntBalance,
1566
+ methTokenAddress,
1567
+ wethTokenAddress,
1568
+ wmntTokenAddress
1569
+ };
1570
+ }
1571
+ async function swapToMeth(agent, amount, slippage = 0.5) {
1572
+ const methTokenAddress = METH_TOKEN[agent.chain];
1573
+ const wethTokenAddress = WETH_TOKEN[agent.chain];
1574
+ if (methTokenAddress === "0x0000000000000000000000000000000000000000") {
1575
+ throw new Error(
1576
+ `mETH not available on ${agent.chain}. Only available on mainnet.`
1577
+ );
1578
+ }
1579
+ const result = await swapOnOpenOcean(
1580
+ agent,
1581
+ wethTokenAddress,
1582
+ methTokenAddress,
1583
+ amount,
1584
+ slippage.toString()
1585
+ );
1586
+ return result.txHash;
1587
+ }
1588
+ async function swapFromMeth(agent, amount, slippage = 0.5) {
1589
+ const methTokenAddress = METH_TOKEN[agent.chain];
1590
+ const wethTokenAddress = WETH_TOKEN[agent.chain];
1591
+ if (methTokenAddress === "0x0000000000000000000000000000000000000000") {
1592
+ throw new Error(
1593
+ `mETH not available on ${agent.chain}. Only available on mainnet.`
1594
+ );
1595
+ }
1596
+ const result = await swapOnOpenOcean(
1597
+ agent,
1598
+ methTokenAddress,
1599
+ wethTokenAddress,
1600
+ amount,
1601
+ slippage.toString()
1602
+ );
1603
+ return result.txHash;
1604
+ }
1605
+
1606
+ // src/constants/pikeperps/index.ts
1607
+ var pikeperps_exports = {};
1608
+ __export(pikeperps_exports, {
1609
+ BONDING_CURVE_MARKET: () => BONDING_CURVE_MARKET,
1610
+ BONDING_CURVE_MARKET_ABI: () => BONDING_CURVE_MARKET_ABI,
1611
+ PERPETUAL_TRADING: () => PERPETUAL_TRADING,
1612
+ PERPETUAL_TRADING_ABI: () => PERPETUAL_TRADING_ABI,
1613
+ PIKE_PERPS_CONFIG: () => PIKE_PERPS_CONFIG
1614
+ });
1615
+ var PERPETUAL_TRADING = {
1616
+ mainnet: "0x0000000000000000000000000000000000000000",
1617
+ // Not deployed yet
1618
+ testnet: "0x8081b646f349c049f2d5e8a400057d411dd657bd"
1619
+ };
1620
+ var BONDING_CURVE_MARKET = {
1621
+ mainnet: "0x0000000000000000000000000000000000000000",
1622
+ testnet: "0x93b268325A9862645c82b32229f3B52264750Ca2"
1623
+ };
1624
+ var PIKE_PERPS_CONFIG = {
1625
+ MAX_LEVERAGE: 100,
1626
+ DEFAULT_LEVERAGE: 10,
1627
+ MIN_LEVERAGE: 1,
1628
+ TRADING_FEE_BPS: 5,
1629
+ // 0.05%
1630
+ LIQUIDATION_REWARD_BPS: 500,
1631
+ // 5%
1632
+ PRICE_DECIMALS: 8
1633
+ // Prices are scaled by 1e8
1634
+ };
1635
+ var PERPETUAL_TRADING_ABI = [
1636
+ {
1637
+ inputs: [
1638
+ { internalType: "address", name: "_pyth", type: "address" }
1639
+ ],
1640
+ stateMutability: "nonpayable",
1641
+ type: "constructor"
1642
+ },
1643
+ {
1644
+ anonymous: false,
1645
+ inputs: [
1646
+ { indexed: true, internalType: "uint256", name: "positionId", type: "uint256" },
1647
+ { indexed: true, internalType: "address", name: "user", type: "address" },
1648
+ { indexed: false, internalType: "uint256", name: "pnl", type: "uint256" },
1649
+ { indexed: false, internalType: "uint256", name: "exitPrice", type: "uint256" }
1650
+ ],
1651
+ name: "PositionClosed",
1652
+ type: "event"
1653
+ },
1654
+ {
1655
+ anonymous: false,
1656
+ inputs: [
1657
+ { indexed: true, internalType: "uint256", name: "positionId", type: "uint256" },
1658
+ { indexed: true, internalType: "address", name: "user", type: "address" },
1659
+ { indexed: false, internalType: "uint256", name: "liquidationPrice", type: "uint256" }
1660
+ ],
1661
+ name: "PositionLiquidated",
1662
+ type: "event"
1663
+ },
1664
+ {
1665
+ anonymous: false,
1666
+ inputs: [
1667
+ { indexed: true, internalType: "uint256", name: "positionId", type: "uint256" },
1668
+ { indexed: true, internalType: "address", name: "user", type: "address" },
1669
+ { indexed: true, internalType: "address", name: "token", type: "address" },
1670
+ { indexed: false, internalType: "bool", name: "isLong", type: "bool" },
1671
+ { indexed: false, internalType: "uint256", name: "size", type: "uint256" },
1672
+ { indexed: false, internalType: "uint256", name: "margin", type: "uint256" },
1673
+ { indexed: false, internalType: "uint256", name: "leverage", type: "uint256" },
1674
+ { indexed: false, internalType: "uint256", name: "entryPrice", type: "uint256" }
1675
+ ],
1676
+ name: "PositionOpened",
1677
+ type: "event"
1678
+ },
1679
+ {
1680
+ inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
1681
+ name: "closePosition",
1682
+ outputs: [],
1683
+ stateMutability: "nonpayable",
1684
+ type: "function"
1685
+ },
1686
+ {
1687
+ inputs: [{ internalType: "address", name: "_token", type: "address" }],
1688
+ name: "getCurrentPrice",
1689
+ outputs: [
1690
+ { internalType: "uint256", name: "currentPrice", type: "uint256" },
1691
+ { internalType: "bool", name: "hasPrice", type: "bool" }
1692
+ ],
1693
+ stateMutability: "view",
1694
+ type: "function"
1695
+ },
1696
+ {
1697
+ inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
1698
+ name: "getLiquidationPrice",
1699
+ outputs: [{ internalType: "uint256", name: "liquidationPrice", type: "uint256" }],
1700
+ stateMutability: "view",
1701
+ type: "function"
1702
+ },
1703
+ {
1704
+ inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
1705
+ name: "getPosition",
1706
+ outputs: [
1707
+ {
1708
+ components: [
1709
+ { internalType: "address", name: "user", type: "address" },
1710
+ { internalType: "address", name: "token", type: "address" },
1711
+ { internalType: "bool", name: "isLong", type: "bool" },
1712
+ { internalType: "uint256", name: "size", type: "uint256" },
1713
+ { internalType: "uint256", name: "margin", type: "uint256" },
1714
+ { internalType: "uint256", name: "leverage", type: "uint256" },
1715
+ { internalType: "uint256", name: "entryPrice", type: "uint256" },
1716
+ { internalType: "uint256", name: "entryTime", type: "uint256" },
1717
+ { internalType: "uint256", name: "lastFundingTime", type: "uint256" },
1718
+ { internalType: "bool", name: "isOpen", type: "bool" }
1719
+ ],
1720
+ internalType: "struct PerpetualTrading.Position",
1721
+ name: "",
1722
+ type: "tuple"
1723
+ }
1724
+ ],
1725
+ stateMutability: "view",
1726
+ type: "function"
1727
+ },
1728
+ {
1729
+ inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
1730
+ name: "getPositionPnL",
1731
+ outputs: [
1732
+ { internalType: "uint256", name: "pnl", type: "uint256" },
1733
+ { internalType: "bool", name: "isProfit", type: "bool" }
1734
+ ],
1735
+ stateMutability: "view",
1736
+ type: "function"
1737
+ },
1738
+ {
1739
+ inputs: [{ internalType: "address", name: "_user", type: "address" }],
1740
+ name: "getUserPositions",
1741
+ outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
1742
+ stateMutability: "view",
1743
+ type: "function"
1744
+ },
1745
+ {
1746
+ inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
1747
+ name: "liquidatePosition",
1748
+ outputs: [],
1749
+ stateMutability: "nonpayable",
1750
+ type: "function"
1751
+ },
1752
+ {
1753
+ inputs: [],
1754
+ name: "maxLeverage",
1755
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1756
+ stateMutability: "view",
1757
+ type: "function"
1758
+ },
1759
+ {
1760
+ inputs: [],
1761
+ name: "minMarginBps",
1762
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1763
+ stateMutability: "view",
1764
+ type: "function"
1765
+ },
1766
+ {
1767
+ inputs: [],
1768
+ name: "nextPositionId",
1769
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1770
+ stateMutability: "view",
1771
+ type: "function"
1772
+ },
1773
+ {
1774
+ inputs: [
1775
+ { internalType: "address", name: "_token", type: "address" },
1776
+ { internalType: "bool", name: "_isLong", type: "bool" },
1777
+ { internalType: "uint256", name: "_margin", type: "uint256" },
1778
+ { internalType: "uint256", name: "_leverage", type: "uint256" }
1779
+ ],
1780
+ name: "openPosition",
1781
+ outputs: [{ internalType: "uint256", name: "positionId", type: "uint256" }],
1782
+ stateMutability: "payable",
1783
+ type: "function"
1784
+ },
1785
+ {
1786
+ inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
1787
+ name: "shouldLiquidate",
1788
+ outputs: [{ internalType: "bool", name: "", type: "bool" }],
1789
+ stateMutability: "view",
1790
+ type: "function"
1791
+ },
1792
+ {
1793
+ inputs: [],
1794
+ name: "tradingFeeBps",
1795
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1796
+ stateMutability: "view",
1797
+ type: "function"
1798
+ }
1799
+ ];
1800
+ var BONDING_CURVE_MARKET_ABI = [
1801
+ {
1802
+ inputs: [{ internalType: "address", name: "_token", type: "address" }],
1803
+ name: "getCurrentPrice",
1804
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1805
+ stateMutability: "view",
1806
+ type: "function"
1807
+ },
1808
+ {
1809
+ inputs: [{ internalType: "address", name: "_token", type: "address" }],
1810
+ name: "isListed",
1811
+ outputs: [{ internalType: "bool", name: "", type: "bool" }],
1812
+ stateMutability: "view",
1813
+ type: "function"
1814
+ },
1815
+ {
1816
+ inputs: [{ internalType: "address", name: "_token", type: "address" }],
1817
+ name: "getCurveProgress",
1818
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1819
+ stateMutability: "view",
1820
+ type: "function"
1821
+ }
1822
+ ];
1823
+
1824
+ // src/tools/pikeperps/openLong.ts
1825
+ async function pikeperpsOpenLong(agent, tokenAddress, margin, leverage = PIKE_PERPS_CONFIG.DEFAULT_LEVERAGE) {
1826
+ const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
1827
+ if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
1828
+ throw new Error(
1829
+ `PikePerps not available on ${agent.chain}. Only available on testnet.`
1830
+ );
1831
+ }
1832
+ if (leverage < PIKE_PERPS_CONFIG.MIN_LEVERAGE || leverage > PIKE_PERPS_CONFIG.MAX_LEVERAGE) {
1833
+ throw new Error(
1834
+ `Leverage must be between ${PIKE_PERPS_CONFIG.MIN_LEVERAGE} and ${PIKE_PERPS_CONFIG.MAX_LEVERAGE}`
1835
+ );
1836
+ }
1837
+ if (agent.demo) {
1838
+ return {
1839
+ positionId: BigInt(Math.floor(Math.random() * 1e3)),
1840
+ txHash: "0xdemo_open_long_tx_hash"
1841
+ };
1842
+ }
1843
+ const marginBigInt = BigInt(margin);
1844
+ const data = encodeFunctionData({
1845
+ abi: PERPETUAL_TRADING_ABI,
1846
+ functionName: "openPosition",
1847
+ args: [tokenAddress, true, marginBigInt, BigInt(leverage)]
1848
+ });
1849
+ const txHash = await agent.client.sendTransaction({
1850
+ to: perpetualTradingAddress,
1851
+ data,
1852
+ value: marginBigInt
1853
+ });
1854
+ const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
1855
+ let positionId = 0n;
1856
+ for (const log of receipt.logs) {
1857
+ try {
1858
+ if (log.topics[0] === "0x2e5b0e8c5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5") {
1859
+ positionId = BigInt(log.topics[1] || "0");
1860
+ break;
1861
+ }
1862
+ } catch {
1863
+ }
1864
+ }
1865
+ if (positionId === 0n) {
1866
+ try {
1867
+ const nextId = await agent.client.readContract({
1868
+ address: perpetualTradingAddress,
1869
+ abi: PERPETUAL_TRADING_ABI,
1870
+ functionName: "nextPositionId"
1871
+ });
1872
+ positionId = nextId - 1n;
1873
+ } catch {
1874
+ }
1875
+ }
1876
+ return {
1877
+ positionId,
1878
+ txHash
1879
+ };
1880
+ }
1881
+ async function pikeperpsOpenShort(agent, tokenAddress, margin, leverage = PIKE_PERPS_CONFIG.DEFAULT_LEVERAGE) {
1882
+ const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
1883
+ if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
1884
+ throw new Error(
1885
+ `PikePerps not available on ${agent.chain}. Only available on testnet.`
1886
+ );
1887
+ }
1888
+ if (leverage < PIKE_PERPS_CONFIG.MIN_LEVERAGE || leverage > PIKE_PERPS_CONFIG.MAX_LEVERAGE) {
1889
+ throw new Error(
1890
+ `Leverage must be between ${PIKE_PERPS_CONFIG.MIN_LEVERAGE} and ${PIKE_PERPS_CONFIG.MAX_LEVERAGE}`
1891
+ );
1892
+ }
1893
+ if (agent.demo) {
1894
+ return {
1895
+ positionId: BigInt(Math.floor(Math.random() * 1e3)),
1896
+ txHash: "0xdemo_open_short_tx_hash"
1897
+ };
1898
+ }
1899
+ const marginBigInt = BigInt(margin);
1900
+ const data = encodeFunctionData({
1901
+ abi: PERPETUAL_TRADING_ABI,
1902
+ functionName: "openPosition",
1903
+ args: [tokenAddress, false, marginBigInt, BigInt(leverage)]
1904
+ });
1905
+ const txHash = await agent.client.sendTransaction({
1906
+ to: perpetualTradingAddress,
1907
+ data,
1908
+ value: marginBigInt
1909
+ });
1910
+ const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
1911
+ let positionId = 0n;
1912
+ for (const log of receipt.logs) {
1913
+ try {
1914
+ if (log.topics[0] === "0x2e5b0e8c5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5") {
1915
+ positionId = BigInt(log.topics[1] || "0");
1916
+ break;
1917
+ }
1918
+ } catch {
1919
+ }
1920
+ }
1921
+ if (positionId === 0n) {
1922
+ try {
1923
+ const nextId = await agent.client.readContract({
1924
+ address: perpetualTradingAddress,
1925
+ abi: PERPETUAL_TRADING_ABI,
1926
+ functionName: "nextPositionId"
1927
+ });
1928
+ positionId = nextId - 1n;
1929
+ } catch {
1930
+ }
1931
+ }
1932
+ return {
1933
+ positionId,
1934
+ txHash
1935
+ };
1936
+ }
1937
+ async function pikeperpsClosePosition(agent, positionId) {
1938
+ const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
1939
+ if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
1940
+ throw new Error(
1941
+ `PikePerps not available on ${agent.chain}. Only available on testnet.`
1942
+ );
1943
+ }
1944
+ if (agent.demo) {
1945
+ return "0xdemo_close_position_tx_hash";
1946
+ }
1947
+ const data = encodeFunctionData({
1948
+ abi: PERPETUAL_TRADING_ABI,
1949
+ functionName: "closePosition",
1950
+ args: [positionId]
1951
+ });
1952
+ const txHash = await agent.client.sendTransaction({
1953
+ to: perpetualTradingAddress,
1954
+ data
1955
+ });
1956
+ await agent.client.waitForTransactionReceipt({ hash: txHash });
1957
+ return txHash;
1958
+ }
1959
+ async function pikeperpsGetPositions(agent, userAddress) {
1960
+ const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
1961
+ const address = userAddress || agent.account.address;
1962
+ if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
1963
+ throw new Error(
1964
+ `PikePerps not available on ${agent.chain}. Only available on testnet.`
1965
+ );
1966
+ }
1967
+ if (agent.demo) {
1968
+ return [
1969
+ {
1970
+ positionId: 1n,
1971
+ token: "0x0000000000000000000000000000000000000001",
1972
+ isLong: true,
1973
+ size: BigInt("1000000000000000000"),
1974
+ // 1 ETH equivalent
1975
+ margin: BigInt("100000000000000000"),
1976
+ // 0.1 ETH
1977
+ leverage: 10,
1978
+ entryPrice: BigInt("100000000"),
1979
+ // $1.00 scaled by 1e8
1980
+ entryTime: BigInt(Math.floor(Date.now() / 1e3) - 3600),
1981
+ currentPrice: BigInt("110000000"),
1982
+ // $1.10
1983
+ pnl: BigInt("10000000000000000"),
1984
+ // 0.01 ETH profit
1985
+ isProfit: true,
1986
+ liquidationPrice: BigInt("90000000"),
1987
+ // $0.90
1988
+ isOpen: true
1989
+ }
1990
+ ];
1991
+ }
1992
+ const positionIds = await agent.client.readContract({
1993
+ address: perpetualTradingAddress,
1994
+ abi: PERPETUAL_TRADING_ABI,
1995
+ functionName: "getUserPositions",
1996
+ args: [address]
1997
+ });
1998
+ if (positionIds.length === 0) {
1999
+ return [];
2000
+ }
2001
+ const positions = [];
2002
+ for (const positionId of positionIds) {
2003
+ try {
2004
+ const rawPosition = await agent.client.readContract({
2005
+ address: perpetualTradingAddress,
2006
+ abi: PERPETUAL_TRADING_ABI,
2007
+ functionName: "getPosition",
2008
+ args: [positionId]
2009
+ });
2010
+ if (!rawPosition.isOpen) {
2011
+ continue;
2012
+ }
2013
+ const [pnl, isProfit] = await agent.client.readContract({
2014
+ address: perpetualTradingAddress,
2015
+ abi: PERPETUAL_TRADING_ABI,
2016
+ functionName: "getPositionPnL",
2017
+ args: [positionId]
2018
+ });
2019
+ const liquidationPrice = await agent.client.readContract({
2020
+ address: perpetualTradingAddress,
2021
+ abi: PERPETUAL_TRADING_ABI,
2022
+ functionName: "getLiquidationPrice",
2023
+ args: [positionId]
2024
+ });
2025
+ let currentPrice = 0n;
2026
+ try {
2027
+ const [price, hasPrice] = await agent.client.readContract({
2028
+ address: perpetualTradingAddress,
2029
+ abi: PERPETUAL_TRADING_ABI,
2030
+ functionName: "getCurrentPrice",
2031
+ args: [rawPosition.token]
2032
+ });
2033
+ if (hasPrice) {
2034
+ currentPrice = price;
2035
+ }
2036
+ } catch {
2037
+ currentPrice = rawPosition.entryPrice;
2038
+ }
2039
+ positions.push({
2040
+ positionId,
2041
+ token: rawPosition.token,
2042
+ isLong: rawPosition.isLong,
2043
+ size: rawPosition.size,
2044
+ margin: rawPosition.margin,
2045
+ leverage: Number(rawPosition.leverage),
2046
+ entryPrice: rawPosition.entryPrice,
2047
+ entryTime: rawPosition.entryTime,
2048
+ currentPrice,
2049
+ pnl,
2050
+ isProfit,
2051
+ liquidationPrice,
2052
+ isOpen: rawPosition.isOpen
2053
+ });
2054
+ } catch (error) {
2055
+ console.warn(`Failed to fetch position ${positionId}:`, error);
2056
+ }
2057
+ }
2058
+ return positions;
2059
+ }
2060
+ async function pikeperpsGetMarketData(agent, tokenAddress, limit = 20) {
2061
+ const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
2062
+ const bondingCurveAddress = BONDING_CURVE_MARKET[agent.chain];
2063
+ if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
2064
+ throw new Error(
2065
+ `PikePerps not available on ${agent.chain}. Only available on testnet.`
2066
+ );
2067
+ }
2068
+ if (agent.demo) {
2069
+ return {
2070
+ token: tokenAddress,
2071
+ currentPrice: BigInt("100000000"),
2072
+ // $1.00 scaled by 1e8
2073
+ hasPrice: true,
2074
+ isListed: true,
2075
+ curveProgress: BigInt("5000"),
2076
+ // 50%
2077
+ recentTrades: [
2078
+ {
2079
+ positionId: 1n,
2080
+ trader: "0x0000000000000000000000000000000000000001",
2081
+ token: tokenAddress,
2082
+ isLong: true,
2083
+ size: BigInt("1000000000000000000"),
2084
+ margin: BigInt("100000000000000000"),
2085
+ leverage: 10n,
2086
+ entryPrice: BigInt("100000000"),
2087
+ timestamp: Math.floor(Date.now() / 1e3) - 300,
2088
+ txHash: "0xdemo_trade_hash",
2089
+ blockNumber: 1000n
2090
+ }
2091
+ ]
2092
+ };
2093
+ }
2094
+ let currentPrice = 0n;
2095
+ let hasPrice = false;
2096
+ try {
2097
+ const [price, hasPriceResult] = await agent.client.readContract({
2098
+ address: perpetualTradingAddress,
2099
+ abi: PERPETUAL_TRADING_ABI,
2100
+ functionName: "getCurrentPrice",
2101
+ args: [tokenAddress]
2102
+ });
2103
+ currentPrice = price;
2104
+ hasPrice = hasPriceResult;
2105
+ } catch {
2106
+ }
2107
+ let isListed = false;
2108
+ let curveProgress = 0n;
2109
+ if (bondingCurveAddress !== "0x0000000000000000000000000000000000000000") {
2110
+ try {
2111
+ isListed = await agent.client.readContract({
2112
+ address: bondingCurveAddress,
2113
+ abi: BONDING_CURVE_MARKET_ABI,
2114
+ functionName: "isListed",
2115
+ args: [tokenAddress]
2116
+ });
2117
+ if (isListed) {
2118
+ curveProgress = await agent.client.readContract({
2119
+ address: bondingCurveAddress,
2120
+ abi: BONDING_CURVE_MARKET_ABI,
2121
+ functionName: "getCurveProgress",
2122
+ args: [tokenAddress]
2123
+ });
2124
+ }
2125
+ } catch {
2126
+ }
2127
+ }
2128
+ const recentTrades = [];
2129
+ try {
2130
+ const currentBlock = await agent.client.getBlockNumber();
2131
+ const fromBlock = currentBlock > 1000n ? currentBlock - 1000n : 0n;
2132
+ const logs = await agent.client.getLogs({
2133
+ address: perpetualTradingAddress,
2134
+ event: parseAbiItem(
2135
+ "event PositionOpened(uint256 indexed positionId, address indexed user, address indexed token, bool isLong, uint256 size, uint256 margin, uint256 leverage, uint256 entryPrice)"
2136
+ ),
2137
+ args: {
2138
+ token: tokenAddress
2139
+ },
2140
+ fromBlock,
2141
+ toBlock: currentBlock
2142
+ });
2143
+ const blockCache = /* @__PURE__ */ new Map();
2144
+ for (const log of logs.slice(-limit)) {
2145
+ let timestamp = 0;
2146
+ if (!blockCache.has(log.blockNumber)) {
2147
+ try {
2148
+ const block = await agent.client.getBlock({
2149
+ blockNumber: log.blockNumber
2150
+ });
2151
+ timestamp = Number(block.timestamp);
2152
+ blockCache.set(log.blockNumber, timestamp);
2153
+ } catch {
2154
+ timestamp = Math.floor(Date.now() / 1e3);
2155
+ }
2156
+ } else {
2157
+ timestamp = blockCache.get(log.blockNumber) || 0;
2158
+ }
2159
+ recentTrades.push({
2160
+ positionId: BigInt(log.topics[1] || "0"),
2161
+ trader: log.topics[2],
2162
+ token: tokenAddress,
2163
+ isLong: log.args.isLong || false,
2164
+ size: log.args.size || 0n,
2165
+ margin: log.args.margin || 0n,
2166
+ leverage: log.args.leverage || 0n,
2167
+ entryPrice: log.args.entryPrice || 0n,
2168
+ timestamp,
2169
+ txHash: log.transactionHash,
2170
+ blockNumber: log.blockNumber
2171
+ });
2172
+ }
2173
+ } catch (error) {
2174
+ console.warn("Failed to fetch recent trades:", error);
2175
+ }
2176
+ return {
2177
+ token: tokenAddress,
2178
+ currentPrice,
2179
+ hasPrice,
2180
+ isListed,
2181
+ curveProgress,
2182
+ recentTrades
2183
+ };
2184
+ }
1185
2185
 
1186
2186
  // src/tools/okx/getSwapQuote.ts
1187
2187
  var getSwapQuote = async (agent, from, to, amount, slippagePercentage) => {
2188
+ if (agent.demo) {
2189
+ return createMockQuoteResponse("OKX", amount);
2190
+ }
1188
2191
  const chainIndex = agent.chain === "mainnet" ? "5000" : "5003";
1189
2192
  return getSwapTransaction(from, to, amount, chainIndex, slippagePercentage);
1190
2193
  };
@@ -1271,21 +2274,44 @@ function getProjectConfig() {
1271
2274
  }
1272
2275
  return cachedConfig;
1273
2276
  }
1274
-
1275
- // src/agent.ts
2277
+ async function getUserAccountData(agent, userAddress) {
2278
+ const lendingPoolAddress = LENDING_POOL[agent.chain];
2279
+ const address = userAddress || agent.account.address;
2280
+ if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
2281
+ throw new Error(
2282
+ `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
2283
+ );
2284
+ }
2285
+ const result = await agent.client.readContract({
2286
+ address: lendingPoolAddress,
2287
+ abi: LENDING_POOL_ABI,
2288
+ functionName: "getUserAccountData",
2289
+ args: [address]
2290
+ });
2291
+ return {
2292
+ totalCollateralETH: result[0],
2293
+ totalDebtETH: result[1],
2294
+ availableBorrowsETH: result[2],
2295
+ currentLiquidationThreshold: result[3],
2296
+ ltv: result[4],
2297
+ healthFactor: result[5]
2298
+ };
2299
+ }
1276
2300
  var MNTAgentKit = class {
1277
2301
  account;
1278
2302
  client;
1279
2303
  chain;
2304
+ demo;
1280
2305
  projectConfig;
1281
2306
  constructor(privateKey, chain) {
1282
2307
  this.account = privateKeyToAccount(privateKey);
1283
- this.chain = chain;
2308
+ this.demo = chain === "testnet-demo";
2309
+ this.chain = chain === "testnet-demo" ? "testnet" : chain;
1284
2310
  this.client = createWalletClient({
1285
- chain: chain == "mainnet" ? mantle : mantleSepoliaTestnet,
2311
+ chain: this.chain == "mainnet" ? mantle : mantleSepoliaTestnet,
1286
2312
  transport: http(),
1287
2313
  account: this.account
1288
- }).extend(publicActions);
2314
+ }).extend(publicActions).extend(erc7811Actions());
1289
2315
  }
1290
2316
  /**
1291
2317
  * Initialize the agent with platform validation
@@ -1320,15 +2346,13 @@ var MNTAgentKit = class {
1320
2346
  );
1321
2347
  }
1322
2348
  async executeSwap(fromTokenAddress, toTokenAddress, amount, slippagePercentage = "0.5") {
1323
- if (this.chain === "mainnet") {
1324
- return await executeSwap(
1325
- this,
1326
- fromTokenAddress,
1327
- toTokenAddress,
1328
- amount,
1329
- slippagePercentage
1330
- );
1331
- }
2349
+ return await executeSwap(
2350
+ this,
2351
+ fromTokenAddress,
2352
+ toTokenAddress,
2353
+ amount,
2354
+ slippagePercentage
2355
+ );
1332
2356
  }
1333
2357
  // OpenOcean DEX Aggregator
1334
2358
  async getOpenOceanQuote(fromToken, toToken, amount) {
@@ -1388,6 +2412,24 @@ var MNTAgentKit = class {
1388
2412
  async lendleRepay(tokenAddress, amount, rateMode = 2, onBehalfOf) {
1389
2413
  return await lendleRepay(this, tokenAddress, amount, rateMode, onBehalfOf);
1390
2414
  }
2415
+ /**
2416
+ * Get user account data from Lendle LendingPool
2417
+ * Returns overall position including total collateral, debt, and health factor
2418
+ * @param userAddress - User wallet address (optional, defaults to agent account)
2419
+ * @returns User account data with collateral, debt, available borrows, and health factor
2420
+ */
2421
+ async lendleGetUserAccountData(userAddress) {
2422
+ return await getUserAccountData(this, userAddress);
2423
+ }
2424
+ /**
2425
+ * Get all Lendle positions for a user (per-token breakdown)
2426
+ * Returns detailed supply and borrow amounts for each asset
2427
+ * @param userAddress - User wallet address (optional, defaults to agent account)
2428
+ * @returns Array of positions with supply/borrow amounts per asset
2429
+ */
2430
+ async lendleGetPositions(userAddress) {
2431
+ return await lendleGetPositions(this, userAddress);
2432
+ }
1391
2433
  // Agni Finance DEX (#1 on Mantle)
1392
2434
  async agniSwap(tokenIn, tokenOut, amountIn, slippagePercent = 0.5, feeTier) {
1393
2435
  return await agniSwap(
@@ -1411,8 +2453,38 @@ var MNTAgentKit = class {
1411
2453
  }
1412
2454
  // mETH Protocol - Liquid Staking Token
1413
2455
  getMethTokenAddress() {
2456
+ if (this.demo) {
2457
+ return METH_TOKEN.mainnet;
2458
+ }
1414
2459
  return METH_TOKEN[this.chain];
1415
2460
  }
2461
+ /**
2462
+ * Get mETH staking position for a user
2463
+ * Returns mETH balance and WETH balance for comparison
2464
+ * @param userAddress - User wallet address (optional, defaults to agent account)
2465
+ * @returns mETH position with balances
2466
+ */
2467
+ async methGetPosition(userAddress) {
2468
+ return await methGetPosition(this, userAddress);
2469
+ }
2470
+ /**
2471
+ * Swap WETH to mETH using DEX aggregator
2472
+ * @param amount - Amount of WETH to swap (in wei as string)
2473
+ * @param slippage - Slippage tolerance percentage (default 0.5%)
2474
+ * @returns Transaction hash
2475
+ */
2476
+ async swapToMeth(amount, slippage = 0.5) {
2477
+ return await swapToMeth(this, amount, slippage);
2478
+ }
2479
+ /**
2480
+ * Swap mETH to WETH using DEX aggregator
2481
+ * @param amount - Amount of mETH to swap (in wei as string)
2482
+ * @param slippage - Slippage tolerance percentage (default 0.5%)
2483
+ * @returns Transaction hash
2484
+ */
2485
+ async swapFromMeth(amount, slippage = 0.5) {
2486
+ return await swapFromMeth(this, amount, slippage);
2487
+ }
1416
2488
  // Squid Router Cross-chain
1417
2489
  async getSquidRoute(fromToken, toToken, fromChain, toChain, amount, slippage = 1) {
1418
2490
  return await getSquidRoute(
@@ -1436,8 +2508,56 @@ var MNTAgentKit = class {
1436
2508
  slippage
1437
2509
  );
1438
2510
  }
2511
+ // PikePerps - Perpetual Trading
2512
+ /**
2513
+ * Open a long position on PikePerps
2514
+ * @param tokenAddress - Token to trade (meme token address)
2515
+ * @param margin - Margin amount in wei (as string)
2516
+ * @param leverage - Leverage multiplier (1-100, default 10)
2517
+ * @returns Position ID and transaction hash
2518
+ */
2519
+ async pikeperpsOpenLong(tokenAddress, margin, leverage = 10) {
2520
+ return await pikeperpsOpenLong(this, tokenAddress, margin, leverage);
2521
+ }
2522
+ /**
2523
+ * Open a short position on PikePerps
2524
+ * @param tokenAddress - Token to trade (meme token address)
2525
+ * @param margin - Margin amount in wei (as string)
2526
+ * @param leverage - Leverage multiplier (1-100, default 10)
2527
+ * @returns Position ID and transaction hash
2528
+ */
2529
+ async pikeperpsOpenShort(tokenAddress, margin, leverage = 10) {
2530
+ return await pikeperpsOpenShort(this, tokenAddress, margin, leverage);
2531
+ }
2532
+ /**
2533
+ * Close an existing position on PikePerps
2534
+ * @param positionId - Position ID to close
2535
+ * @returns Transaction hash
2536
+ */
2537
+ async pikeperpsClosePosition(positionId) {
2538
+ return await pikeperpsClosePosition(this, positionId);
2539
+ }
2540
+ /**
2541
+ * Get all positions for a user on PikePerps
2542
+ * Returns detailed position data including PnL and liquidation prices
2543
+ * @param userAddress - User wallet address (optional, defaults to agent account)
2544
+ * @returns Array of positions with PnL and liquidation data
2545
+ */
2546
+ async pikeperpsGetPositions(userAddress) {
2547
+ return await pikeperpsGetPositions(this, userAddress);
2548
+ }
2549
+ /**
2550
+ * Get market data for a token on PikePerps
2551
+ * Returns current price and recent trades
2552
+ * @param tokenAddress - Token address to get market data for
2553
+ * @param limit - Maximum number of recent trades to return (default 20)
2554
+ * @returns Market data with price and recent trades
2555
+ */
2556
+ async pikeperpsGetMarketData(tokenAddress, limit = 20) {
2557
+ return await pikeperpsGetMarketData(this, tokenAddress, limit);
2558
+ }
1439
2559
  };
1440
2560
 
1441
- export { agni_exports as AgniConstants, lendle_exports as LendleConstants, METH_TOKEN, MNTAgentKit, merchantmoe_exports as MerchantMoeConstants, meth_exports as MethConstants, okx_exports as OKXConstants, oneinch_exports as OneInchConstants, openocean_exports as OpenOceanConstants, squid_exports as SquidConstants, uniswap_exports as UniswapConstants, agniSwap, approveToken, crossChainSwapViaSquid, executeSwap, get1inchQuote, getOpenOceanQuote, getProjectConfig, getSquidRoute, getUniswapQuote, initializePlatform, lendleBorrow, lendleRepay, lendleSupply, lendleWithdraw, merchantMoeSwap, sendTransaction, swapOn1inch, swapOnOpenOcean, swapOnUniswap };
2561
+ export { agni_exports as AgniConstants, lendle_exports as LendleConstants, METH_TOKEN, MNTAgentKit, merchantmoe_exports as MerchantMoeConstants, meth_exports as MethConstants, okx_exports as OKXConstants, oneinch_exports as OneInchConstants, openocean_exports as OpenOceanConstants, pikeperps_exports as PikePerpsConstants, squid_exports as SquidConstants, uniswap_exports as UniswapConstants, agniSwap, approveToken, crossChainSwapViaSquid, executeSwap, get1inchQuote, getOpenOceanQuote, getProjectConfig, getSquidRoute, getUniswapQuote, initializePlatform, lendleBorrow, lendleGetPositions, lendleRepay, lendleSupply, lendleWithdraw, merchantMoeSwap, methGetPosition, pikeperpsClosePosition, pikeperpsGetMarketData, pikeperpsGetPositions, pikeperpsOpenLong, pikeperpsOpenShort, sendTransaction, swapFromMeth, swapOn1inch, swapOnOpenOcean, swapOnUniswap, swapToMeth };
1442
2562
  //# sourceMappingURL=index.js.map
1443
2563
  //# sourceMappingURL=index.js.map