mantle-agent-kit-sdk 1.0.2 → 1.0.3

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/README.md CHANGED
@@ -296,6 +296,27 @@ const mainnetAgent = new MNTAgentKit(privateKey, "mainnet");
296
296
  const testnetAgent = new MNTAgentKit(privateKey, "testnet");
297
297
  ```
298
298
 
299
+ ### Demo/Simulation Mode
300
+
301
+ The SDK includes a demo mode for testing and development without executing real blockchain transactions. In demo mode, all operations return simulated responses instead of making actual on-chain calls.
302
+
303
+ ```typescript
304
+ // Initialize agent in demo mode
305
+ const demoAgent = new MNTAgentKit(privateKey, "testnet-demo");
306
+
307
+ // All operations return mock responses
308
+ const result = await demoAgent.swapOnUniswap(tokenA, tokenB, amount);
309
+ // Returns: { txHash: "0xdemo...", amountOut: "...", demo: true, message: "[DEMO] Uniswap swap simulated" }
310
+ ```
311
+
312
+ Demo mode is useful for:
313
+ - Testing application logic without spending real tokens
314
+ - Development and debugging workflows
315
+ - Integration testing in CI/CD pipelines
316
+ - Demonstrating functionality without wallet funds
317
+
318
+ All protocol methods (swaps, lending operations, cross-chain transfers) support demo mode and return consistent mock response structures with `demo: true` flag.
319
+
299
320
  ## Contract Addresses
300
321
 
301
322
  All protocol contract addresses are pre-configured for Mantle Mainnet:
package/dist/index.cjs CHANGED
@@ -6,6 +6,7 @@ var chains = require('viem/chains');
6
6
  var actions = require('viem/actions');
7
7
  var axios6 = require('axios');
8
8
  var CryptoJS = require('crypto-js');
9
+ var experimental = require('viem/experimental');
9
10
 
10
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
12
 
@@ -17,11 +18,43 @@ var __export = (target, all) => {
17
18
  for (var name in all)
18
19
  __defProp(target, name, { get: all[name], enumerable: true });
19
20
  };
20
- var sendTransaction = async (agent, to, amount) => {
21
- const hash = await agent.client.sendTransaction({
22
- to,
23
- value: viem.parseEther(amount)
24
- });
21
+ var erc20Abi = [
22
+ {
23
+ name: "transfer",
24
+ type: "function",
25
+ inputs: [
26
+ { name: "to", type: "address" },
27
+ { name: "amount", type: "uint256" }
28
+ ],
29
+ outputs: [{ type: "bool" }]
30
+ },
31
+ {
32
+ name: "decimals",
33
+ type: "function",
34
+ inputs: [],
35
+ outputs: [{ type: "uint8" }]
36
+ }
37
+ ];
38
+ var sendTransaction = async (agent, to, amount, tokenAddress) => {
39
+ let hash;
40
+ if (tokenAddress) {
41
+ const decimals = await agent.client.readContract({
42
+ address: tokenAddress,
43
+ abi: erc20Abi,
44
+ functionName: "decimals"
45
+ });
46
+ hash = await agent.client.writeContract({
47
+ address: tokenAddress,
48
+ abi: erc20Abi,
49
+ functionName: "transfer",
50
+ args: [to, viem.parseUnits(amount, decimals)]
51
+ });
52
+ } else {
53
+ hash = await agent.client.sendTransaction({
54
+ to,
55
+ value: viem.parseEther(amount)
56
+ });
57
+ }
25
58
  const receipt = await actions.getTransactionReceipt(agent.client, {
26
59
  hash
27
60
  });
@@ -195,9 +228,85 @@ async function getSwapTransaction(fromTokenAddress, toTokenAddress, amount, user
195
228
  throw error;
196
229
  }
197
230
  }
231
+ var DEMO_TX_HASH = "0xdemo000000000000000000000000000000000000000000000000000000000001";
232
+ function createMockSwapResponse(protocol, inputAmount) {
233
+ return {
234
+ txHash: DEMO_TX_HASH,
235
+ amountOut: inputAmount,
236
+ demo: true,
237
+ message: `[DEMO] ${protocol} swap simulated`
238
+ };
239
+ }
240
+ function createMockQuoteResponse(protocol, inputAmount) {
241
+ return {
242
+ estimatedAmount: inputAmount,
243
+ demo: true,
244
+ message: `[DEMO] ${protocol} quote simulated`
245
+ };
246
+ }
247
+ function createMockLendleResponse(action, amount) {
248
+ return {
249
+ txHash: DEMO_TX_HASH,
250
+ amount,
251
+ demo: true,
252
+ message: `[DEMO] Lendle ${action} simulated`
253
+ };
254
+ }
255
+ function createMockTxHash() {
256
+ return DEMO_TX_HASH;
257
+ }
258
+ function createMock1inchSwapResponse(inputAmount) {
259
+ return {
260
+ txHash: DEMO_TX_HASH,
261
+ dstAmount: inputAmount,
262
+ demo: true,
263
+ message: "[DEMO] 1inch swap simulated"
264
+ };
265
+ }
266
+ function createMockOkxSwapResponse(inputAmount) {
267
+ return {
268
+ data: DEMO_TX_HASH,
269
+ demo: true,
270
+ message: "[DEMO] OKX swap simulated"
271
+ };
272
+ }
273
+ function createMockOpenOceanSwapResponse(inputAmount) {
274
+ return {
275
+ txHash: DEMO_TX_HASH,
276
+ outAmount: inputAmount,
277
+ demo: true,
278
+ message: "[DEMO] OpenOcean swap simulated"
279
+ };
280
+ }
281
+ function createMockUniswapSwapResponse(inputAmount) {
282
+ return {
283
+ txHash: DEMO_TX_HASH,
284
+ amountOut: inputAmount,
285
+ demo: true,
286
+ message: "[DEMO] Uniswap swap simulated"
287
+ };
288
+ }
289
+ function createMockSquidRoute(amount) {
290
+ return {
291
+ route: {
292
+ estimate: { toAmount: amount },
293
+ transactionRequest: {
294
+ targetAddress: "0x0000000000000000000000000000000000000000",
295
+ data: "0x",
296
+ value: "0",
297
+ gasLimit: "0"
298
+ }
299
+ },
300
+ demo: true,
301
+ message: "[DEMO] Squid route simulated"
302
+ };
303
+ }
198
304
 
199
305
  // src/tools/okx/swap.ts
200
306
  async function executeSwap(agent, fromTokenAddress, toTokenAddress, amount, slippagePercent) {
307
+ if (agent.demo) {
308
+ return createMockOkxSwapResponse();
309
+ }
201
310
  const chainIndex = agent.chain === "mainnet" ? "5000" : "5003";
202
311
  const walletAddress = agent.account.address;
203
312
  if (fromTokenAddress !== ETH_ADDRESS) {
@@ -331,6 +440,9 @@ async function getSwapData(fromToken, toToken, amount, userAddress, slippage, ch
331
440
 
332
441
  // src/tools/openocean/getQuote.ts
333
442
  async function getOpenOceanQuote(agent, fromToken, toToken, amount) {
443
+ if (agent.demo) {
444
+ return createMockQuoteResponse("OpenOcean", amount);
445
+ }
334
446
  return await getQuoteData(fromToken, toToken, amount, agent.chain);
335
447
  }
336
448
  async function checkAllowance2(agent, tokenAddress, ownerAddress, spenderAddress) {
@@ -387,6 +499,9 @@ async function approveToken2(agent, tokenAddress, spenderAddress, amount) {
387
499
 
388
500
  // src/tools/openocean/swap.ts
389
501
  async function swapOnOpenOcean(agent, fromToken, toToken, amount, slippage = "1") {
502
+ if (agent.demo) {
503
+ return createMockOpenOceanSwapResponse(amount);
504
+ }
390
505
  const walletAddress = agent.account.address;
391
506
  if (fromToken.toLowerCase() !== NATIVE_TOKEN_ADDRESS.toLowerCase()) {
392
507
  await approveToken2(agent, fromToken, OPENOCEAN_EXCHANGE_PROXY, amount);
@@ -498,11 +613,17 @@ async function getSwapData2(fromToken, toToken, amount, userAddress, slippage, c
498
613
 
499
614
  // src/tools/oneinch/getQuote.ts
500
615
  async function get1inchQuote(agent, fromToken, toToken, amount) {
616
+ if (agent.demo) {
617
+ return createMockQuoteResponse("1inch", amount);
618
+ }
501
619
  return await getQuoteData2(fromToken, toToken, amount, agent.chain);
502
620
  }
503
621
 
504
622
  // src/tools/oneinch/swap.ts
505
623
  async function swapOn1inch(agent, fromToken, toToken, amount, slippage = "1") {
624
+ if (agent.demo) {
625
+ return createMock1inchSwapResponse(amount);
626
+ }
506
627
  const walletAddress = agent.account.address;
507
628
  if (fromToken.toLowerCase() !== NATIVE_TOKEN_ADDRESS2.toLowerCase()) {
508
629
  await approveToken2(agent, fromToken, ONEINCH_ROUTER_ADDRESS, amount);
@@ -669,11 +790,17 @@ function buildSwapCalldata(params, fee = DEFAULT_POOL_FEE) {
669
790
 
670
791
  // src/tools/uniswap/getQuote.ts
671
792
  async function getUniswapQuote(agent, fromToken, toToken, amount, fee = DEFAULT_POOL_FEE) {
793
+ if (agent.demo) {
794
+ return createMockQuoteResponse("Uniswap", amount);
795
+ }
672
796
  return await getUniswapQuoteData(agent, fromToken, toToken, amount, fee);
673
797
  }
674
798
 
675
799
  // src/tools/uniswap/swap.ts
676
800
  async function swapOnUniswap(agent, fromToken, toToken, amount, slippage = "0.5", fee = DEFAULT_POOL_FEE) {
801
+ if (agent.demo) {
802
+ return createMockUniswapSwapResponse(amount);
803
+ }
677
804
  const walletAddress = agent.account.address;
678
805
  const isNativeIn = fromToken.toLowerCase() === NATIVE_TOKEN_ADDRESS3.toLowerCase();
679
806
  const quote = await getUniswapQuoteData(agent, fromToken, toToken, amount, fee);
@@ -772,6 +899,9 @@ async function getRouteData(fromToken, toToken, fromChain, toChain, amount, from
772
899
 
773
900
  // src/tools/squid/crossChainSwap.ts
774
901
  async function crossChainSwapViaSquid(agent, fromToken, toToken, fromChain, toChain, amount, slippage = 1) {
902
+ if (agent.demo) {
903
+ return createMockTxHash();
904
+ }
775
905
  const routeData = await getRouteData(
776
906
  fromToken,
777
907
  toToken,
@@ -800,6 +930,9 @@ async function crossChainSwapViaSquid(agent, fromToken, toToken, fromChain, toCh
800
930
  return hash;
801
931
  }
802
932
  async function getSquidRoute(agent, fromToken, toToken, fromChain, toChain, amount, slippage = 1) {
933
+ if (agent.demo) {
934
+ return createMockSquidRoute(amount);
935
+ }
803
936
  return await getRouteData(
804
937
  fromToken,
805
938
  toToken,
@@ -939,6 +1072,9 @@ var LENDING_POOL_ABI = [
939
1072
  async function lendleSupply(agent, tokenAddress, amount) {
940
1073
  const lendingPoolAddress = LENDING_POOL[agent.chain];
941
1074
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1075
+ if (agent.demo) {
1076
+ return createMockLendleResponse("supply", amount).txHash;
1077
+ }
942
1078
  throw new Error(
943
1079
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
944
1080
  );
@@ -965,6 +1101,9 @@ async function lendleSupply(agent, tokenAddress, amount) {
965
1101
  async function lendleWithdraw(agent, tokenAddress, amount, to) {
966
1102
  const lendingPoolAddress = LENDING_POOL[agent.chain];
967
1103
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1104
+ if (agent.demo) {
1105
+ return createMockLendleResponse("withdraw", amount).txHash;
1106
+ }
968
1107
  throw new Error(
969
1108
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
970
1109
  );
@@ -986,6 +1125,9 @@ async function lendleWithdraw(agent, tokenAddress, amount, to) {
986
1125
  async function lendleBorrow(agent, tokenAddress, amount, interestRateMode = INTEREST_RATE_MODE.VARIABLE, onBehalfOf) {
987
1126
  const lendingPoolAddress = LENDING_POOL[agent.chain];
988
1127
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1128
+ if (agent.demo) {
1129
+ return createMockLendleResponse("borrow", amount).txHash;
1130
+ }
989
1131
  throw new Error(
990
1132
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
991
1133
  );
@@ -1008,6 +1150,9 @@ async function lendleBorrow(agent, tokenAddress, amount, interestRateMode = INTE
1008
1150
  async function lendleRepay(agent, tokenAddress, amount, rateMode = INTEREST_RATE_MODE.VARIABLE, onBehalfOf) {
1009
1151
  const lendingPoolAddress = LENDING_POOL[agent.chain];
1010
1152
  if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
1153
+ if (agent.demo) {
1154
+ return createMockLendleResponse("repay", amount).txHash;
1155
+ }
1011
1156
  throw new Error(
1012
1157
  `Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
1013
1158
  );
@@ -1088,6 +1233,9 @@ var FEE_TIERS2 = {
1088
1233
  async function agniSwap(agent, tokenIn, tokenOut, amountIn, slippagePercent = 0.5, feeTier = FEE_TIERS2.MEDIUM) {
1089
1234
  const swapRouterAddress = SWAP_ROUTER[agent.chain];
1090
1235
  if (swapRouterAddress === "0x0000000000000000000000000000000000000000") {
1236
+ if (agent.demo) {
1237
+ return createMockSwapResponse("Agni", amountIn).txHash;
1238
+ }
1091
1239
  throw new Error(`Agni SwapRouter not available on ${agent.chain}`);
1092
1240
  }
1093
1241
  const amountInBigInt = BigInt(amountIn);
@@ -1160,6 +1308,9 @@ var LB_ROUTER_ABI = [
1160
1308
  async function merchantMoeSwap(agent, tokenIn, tokenOut, amountIn, slippagePercent = 0.5) {
1161
1309
  const routerAddress = LB_ROUTER[agent.chain];
1162
1310
  if (routerAddress === "0x0000000000000000000000000000000000000000") {
1311
+ if (agent.demo) {
1312
+ return createMockSwapResponse("MerchantMoe", amountIn).txHash;
1313
+ }
1163
1314
  throw new Error(`Merchant Moe LB Router not available on ${agent.chain}`);
1164
1315
  }
1165
1316
  const amountInBigInt = BigInt(amountIn);
@@ -1192,6 +1343,9 @@ var METH_TOKEN = {
1192
1343
 
1193
1344
  // src/tools/okx/getSwapQuote.ts
1194
1345
  var getSwapQuote = async (agent, from, to, amount, slippagePercentage) => {
1346
+ if (agent.demo) {
1347
+ return createMockQuoteResponse("OKX", amount);
1348
+ }
1195
1349
  const chainIndex = agent.chain === "mainnet" ? "5000" : "5003";
1196
1350
  return getSwapTransaction(from, to, amount, chainIndex, slippagePercentage);
1197
1351
  };
@@ -1278,21 +1432,21 @@ function getProjectConfig() {
1278
1432
  }
1279
1433
  return cachedConfig;
1280
1434
  }
1281
-
1282
- // src/agent.ts
1283
1435
  var MNTAgentKit = class {
1284
1436
  account;
1285
1437
  client;
1286
1438
  chain;
1439
+ demo;
1287
1440
  projectConfig;
1288
1441
  constructor(privateKey, chain) {
1289
1442
  this.account = accounts.privateKeyToAccount(privateKey);
1290
- this.chain = chain;
1443
+ this.demo = chain === "testnet-demo";
1444
+ this.chain = chain === "testnet-demo" ? "testnet" : chain;
1291
1445
  this.client = viem.createWalletClient({
1292
- chain: chain == "mainnet" ? chains.mantle : chains.mantleSepoliaTestnet,
1446
+ chain: this.chain == "mainnet" ? chains.mantle : chains.mantleSepoliaTestnet,
1293
1447
  transport: viem.http(),
1294
1448
  account: this.account
1295
- }).extend(viem.publicActions);
1449
+ }).extend(viem.publicActions).extend(experimental.erc7811Actions());
1296
1450
  }
1297
1451
  /**
1298
1452
  * Initialize the agent with platform validation
@@ -1327,15 +1481,13 @@ var MNTAgentKit = class {
1327
1481
  );
1328
1482
  }
1329
1483
  async executeSwap(fromTokenAddress, toTokenAddress, amount, slippagePercentage = "0.5") {
1330
- if (this.chain === "mainnet") {
1331
- return await executeSwap(
1332
- this,
1333
- fromTokenAddress,
1334
- toTokenAddress,
1335
- amount,
1336
- slippagePercentage
1337
- );
1338
- }
1484
+ return await executeSwap(
1485
+ this,
1486
+ fromTokenAddress,
1487
+ toTokenAddress,
1488
+ amount,
1489
+ slippagePercentage
1490
+ );
1339
1491
  }
1340
1492
  // OpenOcean DEX Aggregator
1341
1493
  async getOpenOceanQuote(fromToken, toToken, amount) {
@@ -1418,6 +1570,9 @@ var MNTAgentKit = class {
1418
1570
  }
1419
1571
  // mETH Protocol - Liquid Staking Token
1420
1572
  getMethTokenAddress() {
1573
+ if (this.demo) {
1574
+ return METH_TOKEN.mainnet;
1575
+ }
1421
1576
  return METH_TOKEN[this.chain];
1422
1577
  }
1423
1578
  // Squid Router Cross-chain